петли глубже в объекте с помощью рекурсии - PullRequest
0 голосов
/ 30 января 2019

я пытался зациклить объект глубже, потому что у этого объекта есть дерево, и очень глубоко, чтобы иметь возможность сделать его зацикливаться и получать данные, я должен попытаться его переписать, я застрял здесь, и результат 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.left и operations.right.left, но когда я возвращаю его,результат не определен и нечего хвастаться

я что-то пропустил ??пример для условия else

Если операция равна '*', тогда я console.log и operation.left и operation.right.left показывает числа, а я пытался умножить его на console.log, он показываетрезультат

Ответы [ 4 ]

0 голосов
/ 30 января 2019

Давайте сделаем это максимально простым.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: ^

Развернитефрагмент ниже для проверки результатов в вашем собственном браузере -

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
  )
0 голосов
/ 30 января 2019

Вы можете использовать деструктурирующее присвоение в деталях left, right и op и вспомогательный объект для операторов и их функций.

Затем проверьте left и right операнды, если они являются объектами, затем сделать рекурсивный вызов функции с этим объектом или просто передать значение.

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
0 голосов
/ 30 января 2019

Я немного переписал ваш код, используя оператор 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))
0 голосов
/ 30 января 2019

Ваш код исправлен ниже:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...