我有一个公式和一个包含变量的对象作为键 我的目标是
{
xyz:{
v:20
},
ab:{
v:2
},
y:{
v:30
},
z:{
v:40
},
}
现在我必须评估公式
例如
xyz+ab*(y+z)
结果:20 + 2 *(30 + 40)
任何优化的解决方案?
请注意,密钥的形式为"字符...字符" 例如。
ABC..XY12
更新:实际对象是
{
pnl..xyz:{
v:20
},
pxl..ab:{
v:2
},
pnl..y:{
v:30
},
pxl..z:{
v:40
},
}
,公式是
pnl..xyz+pxl..ab*(pnl..y+pxl..z)
答案 0 :(得分:2)
您可以使用正则表达式查找变量名称并发布可以使用eval
var data={xyz:{v:20},ab:{v:2},y:{v:30},z:{v:40},abc12:{v:12},"abc..bc":{v:31}};
function processOperation(str) {
var formula = str;
var operatios = /[+\-\*\/\(\)]/g;
var keys = formula.split(operatios);
keys.forEach(function(k) {
if (k && data[k]) formula = formula.replace(k, data[k].v)
});
console.log(formula);
return eval(formula)
}
var formula1 = "xyz+ab*(y+z)"
console.log(processOperation(formula1))
var formula2 = "xyz+ab*(y+z)-abc12"
console.log(processOperation(formula2))
var formula3 = "xyz+ab*(y+z)-12"
console.log(processOperation(formula3))
var formula4 = "xyz+ab*(y+z)-abc..bc"
console.log(processOperation(formula4))
答案 1 :(得分:1)
您可以编写自己的自定义解析器和求值程序,但是会出现大量边缘情况,验证和运算符优先级情况 已搞定。 我建议不要重新发明轮子,并使用math.js,它是一个轻量级的专用库,用于javascript中的数学。 以下是如何在一行中完成公式评估。
var scope = { xyz : 20, ab : 2, y : 30, z : 40 };
var answer = math.eval('xyz+ab*(y+z)', scope);
console.log('The answer is:' + answer);

<script src="http://cdnjs.cloudflare.com/ajax/libs/mathjs/3.5.3/math.min.js"></script>
&#13;
答案 2 :(得分:0)
此函数将替换提供的obj
字符串中提供的formula
的键。它是咖喱的,所以你可以重复使用不同的变量值的相同公式。
const obj = {
xyz:{ v:20 },
ab:{ v:2 },
y:{ v:30 },
z:{ v:40 }
}
const obj2 = {
'pnl..xyz':{ v:20 },
'pxl..ab':{ v:2 },
'pnl..y':{ v:30 },
'pxl..z':{ v:40 },
}
/*
* evalFormula :: String -> {key:{v:Int}} -> String
*
* replace the formula string with the obj values
*/
const evalFormula = formula => obj => {
// get the keys
const keys = Object.keys(obj)
// sort keys by length so we replace the longer strings first
keys.sort(sortBy('length'))
// reduce the keys into the formula
return keys.reduce((str, key) =>
// replace the key with it's corresponding value each iteration
str.replace(stringToRegex(key, 'g'), obj[key].v)
, formula)
}
// get a regular expression from an input string
const stringToRegex = (str, modifiers) =>
new RegExp(str.replace(/([\.\^\$\*\+\-\?\(\)\[\]\{\}\\])/g, '\$1'), modifiers)
const sortBy = prop => (a, b) => a[prop] > b[prop] ? -1 : a[prop] < b[prop] ? 1 : 0
// this is the executable function
const execFormula = evalFormula('xyz+ab*(y+z)')
const otherFormula = evalFormula('pnl..xyz+pxl..ab*(pnl..y+pxl..z)')
console.log(
execFormula(obj),
otherFormula(obj2)
)
&#13;
编辑。
你只需要为你的钥匙中的非法字符添加一点逃脱,然后创建一个新的公式并传入新的obj