【问题标题】:loops deeper in object by recursion通过递归在对象中循环更深
【发布时间】:2019-06-23 18:28:22
【问题描述】:

我试图将对象循环得更深,因为这个对象有树,而且非常深,为了能够让它循环并获取数据,我应该尝试递归它,我被困在这里,结果是undefined

这是数据,输出在里面:

function operationEvaluator(operation) {
  Object.keys(operation).forEach(el => {
    if(typeof operation[el] === 'object'){
      return operationEvaluator(operation[el])
    }
    if(typeof operation[el] === 'number'){
       return operation.left + operationEvaluator(operation.op)
    } else {
      if(operation.op == '-'){
        return operation.left - operation.right.left
      } else if( operation.op == '*'){
        // console.log(operation.left*operation.right.left);
        return operation.left * operation.right.left
      } else if(operation.op == '+' ){
        return operation.left + operation.right.left
      } else if(operation.op == '/'  ){
        return operation.left / operation.right.left
      }
    }
  })
}


var op1 = {
  left: 5,
  op: '-',
  right: {
    left: 3,
    op: '*',
    right: {
      left: 8,
      op: '-',
      right: {
        left: 200,
        op: '/',
        right: 5,
      }
    }
  }
};

// prosses: 5 - (3 * (8 - (200 / 5)))
console.log(operationEvaluator(op1)); // 101

var op2 = {
  left: {
    left: 10,
    op: '*',
    right: {
      left: 2,
      op: '+',
      right: 1,
    },
  },
  op: '+',
  right: {
    left: 5,
    op: '*',
    right: {
      left: 1,
      op: '-',
      right: {
        left: 1,
        op: '+',
        right: 2,
      }
    }
  }
};

// prosses: ((10 * (2 + 1)) + (5 * (1 - (1 + 2)))
console.log(operationEvaluator(op2)); // 20

我尝试console.log最后一个条件else中的每个数据,它显示了operation.leftoperations.right.left的数量 但是当我返回它时,结果是未定义的,没有什么可炫耀的

我错过了什么吗? else 条件下的示例

IF 运算等于'*' 然后我控制台记录 operation.left 和 operation.right.left 它显示了数字,我试图将它乘以 console.log,它显示了结果,

【问题讨论】:

    标签: javascript json object recursion


    【解决方案1】:

    让我们尽可能简单。 eval 接受表达式 e -

    const eval = e =>
      // if the expression is an object ...
      Object (e) === e
        // apply the operator to the evaluated operands ...
        ? apply (e.op, eval (e.left), eval (e.right))
        // otherwise the expression is already a primitive
        : e
    

    apply 也很简单 -

    const env =
      { '+': (a, b) => a + b
      , '-': (a, b) => a - b
      , '*': (a, b) => a * b
      , '/': (a, b) => a / b
      }
    
    const apply = (f, ...args) =>
    { if (env[f] === undefined)
        throw Error (`unknown operator: ${f}`)
      else
        return env[f] (...args)
    }
    

    试试看-

    eval (op1)
    // 101
    
    eval (op2)
    // 20
    
    eval ({ left: 10, op: '^', right: 2 })
    // unknown operator: ^
    

    展开下面的sn-p,在自己的浏览器中验证结果-

    const env =
      { '+': (a, b) => a + b
      , '-': (a, b) => a - b
      , '*': (a, b) => a * b
      , '/': (a, b) => a / b
      }
    
    const eval = e =>
      Object (e) === e
        ? apply (e.op, eval (e.left), eval (e.right))
        : e
      
    const apply = (f, ...args) =>
    { if (env[f] === undefined)
        throw Error (`unknown operator: ${f}`)
      else
        return env[f] (...args)
    }
    
    const op1 =
      { left: 5, op: '-', right: { left: 3, op: '*', right: { left: 8, op: '-', right: { left: 200, op: '/', right: 5 } } } }
    
    const op2 =
      { left: { left: 10, op: '*', right: { left: 2, op: '+', right: 1, }, }, op: '+', right: { left: 5, op: '*', right: { left: 1, op: '-', right: { left: 1, op: '+', right: 2 } } } }
    
    console .log
      ( eval (op1) // 101
      , eval (op2) // 20
      )

    【讨论】:

      【解决方案2】:

      我稍微重写了您的代码,使用switch 语句作为运算符:

      const operationEvaluator = operation => {
      
        let left = (typeof operation.left === "number") ? operation.left : operationEvaluator(operation.left),
          right = (typeof operation.right === "number") ? operation.right : operationEvaluator(operation.right);
      
        switch (operation.op) {
          case "*":
            return left * right
          case "/":
            return left / right
          case "+":
            return left + right
          case "-":
            return left - right
        }
      }
      
      var op1 = { left: 5, op: '-', right: { left: 3, op: '*', right: { left: 8, op: '-', right: { left: 200, op: '/', right: 5 } } } },
      op2 = { left: { left: 10, op: '*', right: { left: 2, op: '+', right: 1, }, }, op: '+', right: { left: 5, op: '*', right: { left: 1, op: '-', right: { left: 1, op: '+', right: 2 } } } };
      
      
      console.log(operationEvaluator(op1))
      console.log(operationEvaluator(op2))

      【讨论】:

      • 好吧,尽管我是 Nina 代码优雅的第一个粉丝,但我不得不承认这种小递归不需要对象解构,而且我也认为这要简单得多。
      【解决方案3】:

      您可以在 leftrightop 部分中使用 destructuring assignment,并为运算符及其函数使用辅助对象。

      然后检查leftright 操作数是否为对象,然后使用该对象对函数进行递归调用或直接交出值。

      function operationEvaluator({ left, op, right }) {
          const
              operators = {
                  '+': (a, b) => a + b,
                  '-': (a, b) => a - b,
                  '*': (a, b) => a * b,
                  '/': (a, b) => a / b
              },
              getOperand = o => typeof o === 'object'
                  ? operationEvaluator(o)
                  : o;
      
          return operators[op](getOperand(left), getOperand(right));
      }
      
      var op1 = { left: 5, op: '-', right: { left: 3, op: '*', right: { left: 8, op: '-', right: { left: 200, op: '/', right: 5 } } } },
          op2 = { left: { left: 10, op: '*', right: { left: 2, op: '+', right: 1, }, }, op: '+', right: { left: 5, op: '*', right: { left: 1, op: '-', right: { left: 1, op: '+', right: 2 } } } };
      
      // prosses: 5 - (3 * (8 - (200 / 5)))
      console.log(operationEvaluator(op1)); // 101
      // prosses: ((10 * (2 + 1)) + (5 * (1 - (1 + 2)))
      console.log(operationEvaluator(op2)); // 20

      【讨论】:

      • 我在想,“我很想看看 Nina 对这个问题的回答”,然后……你来了 :)
      【解决方案4】:

      您的代码固定在下面:

      function operationEvaluator(operation) {
          let computedRightTerm;
          let computedLeftTerm;
          if(typeof operation.right === 'number') {
            computedRightTerm = operation.right;
          }
          else {
            computedRightTerm = operationEvaluator(operation.right);
          }
          if(typeof operation.left=== 'number') {
            computedLeftTerm= operation.left;
          }
          else {
            computedLeftTerm= operationEvaluator(operation.left);
          }
          if(operation.op == '-'){
            return computedLeftTerm - computedRightTerm;
          } else if( operation.op == '*'){
            // console.log(operation.left*operation.right.left);
            return computedLeftTerm * computedRightTerm;
          } else if(operation.op == '+' ){
            return computedLeftTerm + computedRightTerm;
          } else if(operation.op == '/'  ){
            return computedLeftTerm / computedRightTerm;
          }
      }
      
      
      var op1 = {
        left: 5,
        op: '-',
        right: {
          left: 3,
          op: '*',
          right: {
            left: 8,
            op: '-',
            right: {
              left: 200,
              op: '/',
              right: 5,
            }
          }
        }
      };
      
      // prosses: 5 - (3 * (8 - (200 / 5)))
      console.log(operationEvaluator(op1)); // 101
      
      var op2 = {
        left: {
          left: 10,
          op: '*',
          right: {
            left: 2,
            op: '+',
            right: 1,
          },
        },
        op: '+',
        right: {
          left: 5,
          op: '*',
          right: {
            left: 1,
            op: '-',
            right: {
              left: 1,
              op: '+',
              right: 2,
            }
          }
        }
      };
      
      // prosses: ((10 * (2 + 1)) + (5 * (1 - (1 + 2)))
      console.log(operationEvaluator(op2)); // 20

      【讨论】:

        猜你喜欢
        • 2017-07-18
        • 2021-05-09
        • 2020-02-25
        • 1970-01-01
        • 1970-01-01
        • 2021-05-19
        • 2020-11-25
        • 1970-01-01
        • 2020-12-06
        相关资源
        最近更新 更多