Как преобразовать строку математического уравнения в структуру json и проанализировать с помощью JavaScript?

#javascript #json

#javascript #json

Вопрос:

Это пример строки математического уравнения "((VAR1 VAR2)/VAR3)*VAR4)"

Это мой подход к структуре json, поскольку есть прецеденты, было бы неплохо (я думаю) сопоставить результаты для каждой строки.

 {
"variables":[
  {"code":"var1","value":5},
  {"code":"var2","value":10},
  {"code":"var3","value":2},
  {"code":"var4","value":20}
],
'expression':[
  {"fPart":"fp1",  "p1":"var1", "operation": " ", "p2":"var2"},
  {"fPart":"fp2",  "p1":"fp1", "operation": "/", "p2":"var3"},
  {"fPart":"fp3",  "p1":"fp2", "operation": "*", "p2":"var4"}]
} 
 

Я изо всех сил пытаюсь получить какой-нибудь эффективный код function parse() , который мог бы прочитать этот json и вывести проанализированную строку "((VAR1 VAR2)/VAR3)*VAR4)" , в данном случае 5 10/2*20

   //
  fillExpressionWithValues(variableArray, expressionArray) {
    for (let expression of expressionArray) {
      let f1 = variableArray.find(x => x.code == expression.p1);
      let f2 = variableArray.find(x => x.code == expression.p2);
      if (f1) expression.p1 = JSON.parse(f1.value);
      if (f2) expression.p2 = JSON.parse(f2.value);
    }
  }

  //
  calculateExpression(expressionArray) {
    for (let expression of expressionArray) {
      let fPart = this.parse(expression.p1   expression.operation   expression.p2);
      let f1 = expressionArray.find(x => x.p1 == expression.fPart);
      let f2 = expressionArray.find(x => x.p2 == expression.fPart);
      if (f1) {
        f1.p1 = JSON.parse(fPart);
      }
      if (f2) {
        f2.p2 = JSON.parse(fPart);
      }
      expression.fPart = JSON.parse(fPart);
    }
  }
 

Ответ №1:

 const config = {
    "variables": [
        { "code": "var1", "value": 5 },
        { "code": "var2", "value": 10 },
        { "code": "var3", "value": 2 },
        { "code": "var4", "value": 20 },
    ],
    "expression": [
        { "fPart": "fp1", "p1": "var1", "operation": " ", "p2": "var2" },
        { "fPart": "fp2", "p1": "fp1", "operation": "/", "p2": "var3" },
        { "fPart": "fp3", "p1": "fp2", "operation": "*", "p2": "var4" },
    ],
};

let result = '';
for (const expressionStep of config.expression) {
    const left = config.variables.find(v => v.code === expressionStep.p1).value;
    const right = config.variables.find(v => v.code === expressionStep.p2).value;
    const newValue = '('   left   expressionStep.operation   right   ')';
    config.variables.push({ code: expressionStep.fPart, value: newValue });
    result = newValue;
}
console.log(result); 

Комментарии:

1. вау, я был не так уж далек от этого! У меня было это для и это 2 .find() также. Я просто подумал, что это не может быть лучшим подходом, не чувствовал себя чистым. Мне нужно больше доверять себе. Спасибо @Stratubas

Ответ №2:

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

Это может выглядеть так:

 const
  input = getJSON(),
  parsed = parseMath(input);
console.log("parsed:", parsed);

function parseMath(json){
  // Puts variables into a simple object
  const vars = {};
  for(let variable of json.variables){
    vars[variable.code] = variable.value;
  }
  // Copies "expression" array to avoid mutation
  const exprs = json.expression.slice();
  // Builds string, and adds it to expr object and vars object
  for(let expr of exprs){
    expr.stringRepresention = `(${vars[expr.p1]}${expr.operation}${vars[expr.p2]})`;
    vars[expr.fPart] = expr.stringRepresention;
  }
  // Gets the string representation from the final expr object
  return exprs.reverse()[0]["stringRepresention"];
}

function getJSON(){
  return {
    "variables": [
      { "code": "var1", "value": 5  },
      { "code": "var2", "value": 10 },
      { "code": "var3", "value": 2  },
      { "code": "var4", "value": 20 }
    ],
    'expression': [
      { "fPart": "fp1", "p1": "var1", "operation": " ", "p2": "var2" },
      { "fPart": "fp2", "p1": "fp1",  "operation": "/", "p2": "var3" },
      { "fPart": "fp3", "p1": "fp2",  "operation": "*", "p2": "var4" }
    ]
  };
} 

Ответ №3:

 const mathObj = {
"variables":[
  {"code":"var1","value":5},
  {"code":"var2","value":10},
  {"code":"var3","value":2},
  {"code":"var4","value":20}
],
'expression':[
  {"fPart":"fp1",  "p1":"var1", "operation": " ", "p2":"var2"},
  {"fPart":"fp2",  "p1":"fp1", "operation": "/", "p2":"var3"},
  {"fPart":"fp3",  "p1":"fp2", "operation": "*", "p2":"var4"}]
} 
let evals = new Map(mathObj.variables.map(x=>[x.code,x.value]));
mathObj.expression.forEach(x=>{
    if(evals.has(x.p1) amp;amp; evals.has(x.p2)){
        evals.set(x.fPart, `(${evals.get(x.p1)}${x.operation}${evals.get(x.p2)})`)
    }
});
evals.get(mathObj.expression[mathObj.expression.length-1].fPart);