Как разобрать строку, содержащую вычисление, и выполнить ее - PullRequest
0 голосов
/ 11 декабря 2018

У меня следующая ситуация

Итак, у меня есть объект, похожий на этот

var y = {
  "data": {
    "m": 2,
    "n": "meaow",
    "k": "lop",
    "r": {
      "val": 400,
      "text": "Hoila papi"
    }
  }
}

Теперь я хочу дать своему пользователю написать формулу, которую я могу анализировать на основе этого объекта.как это

var  x = {
            "calculation": "((@data>m# * 100) + (@data>r>val# / 200))",
            "target": "data>m"
 }

Есть ли способ, которым это можно сделать в Javascript, поэтому конечный результат должен быть

{
  "data": {
    "m": 202,
    "n": "meaow",
    "k": "lop",
    "r": {
      "val": 400,
      "text": "Hoila papi"
    }
  }
}

1 Ответ

0 голосов
/ 11 декабря 2018

Используйте регулярное выражение для сопоставления строк @prop>prop... и замените их соответствующим значением, используя reduce в массиве свойств.Предполагая, что входные данные заслуживают доверия, вы можете eval получившуюся математическую строку и использовать тот же метод reduce, чтобы найти вложенный объект для обновления.

Обратите внимание, что ((200 * 100) + (400 / 200)) приводит к 20002,не 202:

var y = {
  "data": {
    "m": 200,
    "n": "meaow",
    "k": "lop",
    "r": {
      "val": 400,
      "text": "Hoila papi"
    }
  }
}

var x = {
  "calculation": "((@data>m# * 100) + (@data>r>val# / 200))",
  "target": "data>m"
};
const getNested = (propArr, initial) => propArr.reduce((a, prop) => a[prop], initial);
const mathStr = x.calculation.replace(/@(\S+)#/g, (_, propStr) => (
  Number(getNested(propStr.split('>'), y))
));
console.log(mathStr);
if (/[^-+/*0-9() ]/.test(mathStr)) {
  throw new Error('Unrecognized, potentially unsafe character found');
}

const targetPropArr = x.target.split('>');
const lastProp = targetPropArr.pop();
const lastObj = getNested(targetPropArr, y);
lastObj[lastProp] = eval(mathStr);

console.log(y);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...