如何在不使用EVAL的情况下处理两个阵列对象



我想要处理两个对象。

obj1具有公式的数组对象。

obj2具有值。我想处理/计算这两个对象以获得结果,使obj1中的键成为输出中的实际键,并用公式处理值。使用EVAL完成,但不想使用EVAL。

请建议其他方法来做同样的事情。

const obj1 = [{ _id: '5 f467650890a7444d8d9ea5b', keyname: 'fTime', 
PTag: '(FaultHrs*360)+(FaultMins*60)+FaultSecs',    __v: 0 },
{ _id: '5 f467650890a7444d8d9ea5b', keyname: 'rTime',
PTag: '(RunHrs*360)+(RunMins*60)+RunSecs', __v: 0 }
]
const obj2 = { FaultHrs: 2, FaultMins: 0, FaultSecs: 49, RunHrs: 1, RunMins: 0, RunSecs: 0,}
const res = obj1.reduce((res, k) => {
// find out parameters in formula
const matches = k.PTag.match(/[a-zA-Z]+/g);
// substitute them with numbers
const newTag = matches.reduce((tag, m) => tag.replace(m, obj2[m] || 0), k.PTag);
// calculate result
res[k.keyname] = eval(newTag);
return res;
}, {});
console.log(res)

您可以尝试使用New Function()构造,而不是eval()。更改代码行

res[k.keyname] = eval(newTag);

进入

res[k.keyname] = (new Function(`return ${newTag};`))();

但在引擎盖下,它实际上是相同的eval((。或者,你可以尝试通过抽象语法树来滚动你自己的数学表达式解析器,但互联网上已经有很多了,而且不能保证你的解析器会优于经过时间测试的集成JS引擎表达式解析器。

您可以尝试使用math.js这样的模块,它包含一个求值函数,该函数不在后台使用eval(我相信旧版本确实使用了(。

仍然存在安全风险,它们在math.js文档math.js安全性中有详细说明,但应该低于直接使用eval。

const obj1 = [{ _id: '5 f467650890a7444d8d9ea5b', keyname: 'fTime', 
PTag: '(Fault_Hrs1*360)+(Fault_Mins1*60)+Fault_Secs1',    __v: 0 },
{ _id: '5 f467650890a7444d8d9ea5b', keyname: 'rTime',
PTag: '(RunHrs*360)+(RunMins*60)+RunSecs', __v: 0 }
]
const obj2 = { Fault_Hrs1: 2, Fault_Mins1: 0, Fault_Secs1: 49, RunHrs: 1, RunMins: 0, RunSecs: 0,}
const res = obj1.reduce((res, k) => {
// find out parameters in formula
const matches = k.PTag.match(/([a-zA-Z]{1}[a-zA-Z0-9_]+)/g);

// substitute them with numbers
const newTag = matches.reduce((tag, m) => tag.replace(m, obj2[m] || 0), k.PTag);
// calculate result, using math.js evaluate function.
res[k.keyname] = math.evaluate(newTag);
return res;
}, {});
console.log(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/7.2.0/math.js" integrity="sha512-O3GZu6Lz0va4Lk7IuF3CjKx5Jfxi35Gcx3oAjH7m7KRP5xvqorrInDpg3OFVJ6dMPn03vHiwgkgPT/hWfguVfQ==" crossorigin="anonymous"></script>

Math.js评估函数运行良好,但当值(如3.2477216E7(包含字母表"时;E";,然后它就坏了。你能告诉我怎么处理吗。

const obj1 = [{ _id: '5 f467650890a7444d8d9ea5b', keyname: 'fTime', 
PTag: '(FaultHrs*360)+(FaultMins*60)+FaultSecs',    __v: 0 },
{ _id: '5 f467650890a7444d8d9ea5b', keyname: 'rTime',
PTag: '(RunHrs*360)+(RunMins*60)+RunSecs', __v: 0 }
]
const obj2 = { FaultHrs: 2, FaultMins: 0, FaultSecs: 3.2477216E7, RunHrs: 1, RunMins: 0, RunSecs: 3.2477063E7}
const res = obj1.reduce((res, k) => {
// find out parameters in formula
const matches = k.PTag.match(/[a-zA-Z]+/g);
// substitute them with numbers
const newTag = matches.reduce((tag, m) => tag.replace(m, obj2[m] || 0), k.PTag);
// calculate result, using math.js evaluate function.
res[k.keyname] = math.evaluate(newTag);
return res;
}, {});
console.log(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/7.2.0/math.js" integrity="sha512-O3GZu6Lz0va4Lk7IuF3CjKx5Jfxi35Gcx3oAjH7m7KRP5xvqorrInDpg3OFVJ6dMPn03vHiwgkgPT/hWfguVfQ==" crossorigin="anonymous"></script>

最新更新