2
votes

boucle plus profondément dans l'objet par récursivité

J'ai essayé de boucler l'objet plus profondément parce que cet objet a un arbre, et très profond, pour pouvoir le faire en boucle et obtenir les données, je devrais essayer de le répéter, je suis resté coincé ici et le résultat est indéfini

voici les données et la sortie est à l'intérieur:

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

J'ai essayé de console.log chaque donnée dans la dernière condition else , cela montre le nombre de operation.left code > et operations.right.left mais quand je le retourne, le résultat est indéfini et rien à montrer

Suis-je manqué quelque chose ?? exemple sur la condition else

Si l'opération vaut '*' puis je console.log le operation.left et operation.right.left il montre les nombres et j'ai essayé de le multiplier par console.log, il montre le résultat,


0 commentaires

4 Réponses :


1
votes

Votre code corrigé ci-dessous:

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


0 commentaires


0
votes

J'ai légèrement réécrit votre code, en utilisant une instruction switch pour les opérateurs:

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))


1 commentaires

Eh bien, autant je suis le premier fan de l'élégance du code de Nina, je dois admettre que la déstructuration des objets n'est pas nécessaire pour ce genre de petite récursivité, et je pense aussi que c'est beaucoup plus simple.



0
votes

Rendons les choses aussi simples que possible. eval prend une expression e -

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
  )

apply est aussi simple -

eval (op1)
// 101

eval (op2)
// 20

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

Essayez et voyez -

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)
}

Développez l'extrait ci-dessous pour vérifier les résultats dans votre propre navigateur -

p >

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


0 commentaires