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,
4 Réponses :
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
Je pensais: "Je serais curieux de voir la réponse de Nina à cette question" et ... vous y êtes :)
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))
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.
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