我正在开发一个 API,它将采用 2 个对象和一个表达式并执行过滤错误语句。返回第三个对象,该对象将仅具有表达式被评估为 true 的那些数据集。
var obj1 = [
{cn: 101, name: "AA", seq:1},
{cn: 106, name: "BB", seq:2}
];
var obj2 = [
{ cid: 100, name: "XX", locator: "r" },
{ cid: 101, name: "AA", locator: "p"},
{ cid: 507, name: "TT", locator: "r"}
];
var output = MyClass.filter(obj1, obj2, "{source.cn}==={target.cid}");
obj1 is source object
obj2 is target object
expected output is:
output = [
{ cid: 101, name: "AA", locator: "p"}
];
因为我的类是一个通用类,它应该能够接受任何两个对象(任何结构和深度)并执行任何有效的 javascript 表达式。因此我找到给定表达式的路径并准备表达式列表。
source[0]["cn"]===target[0]["cid"]
source[0]["cn"]===target[1]["cid"]
source[0]["cn"]===target[2]["cid"]
source[1]["cn"]===target[0]["cid"]
source[1]["cn"]===target[1]["cid"]
source[1]["cn"]===target[2]["cid"]
得到表达式后,我评估每个表达式并过滤掉错误的表达式。
eval(source[0]["cn"]===target[0]["cid"]) >>>>>EVAL RESULT>>>>> false
eval(source[0]["cn"]===target[1]["cid"]) >>>>>EVAL RESULT>>>>> true
eval(source[0]["cn"]===target[2]["cid"]) >>>>>EVAL RESULT>>>>> false
eval(source[1]["cn"]===target[0]["cid"]) >>>>>EVAL RESULT>>>>> false
eval(source[1]["cn"]===target[1]["cid"]) >>>>>EVAL RESULT>>>>> false
eval(source[1]["cn"]===target[2]["cid"]) >>>>>EVAL RESULT>>>>> false
当这 2 个对象包含 obj1 100 个可能的路径和 obj2 1000 个可能的路径时,myclass 生成 100,000 条语句来 eval。就是这样,它永远运行着众所周知的 eval 很慢,但由于这些语句是字符串,我无法将它放在“if”中
我尝试了一个测试代码,我在 if 语句中使用了语句,它非常 - 非常快。我想使用 if over eval。
我的测试代码如下:
var before = Date.now();
var str, result, results = [], m, n;
for(var i = 0, j=0; i <100000, j<100000; ++i,++j ){
str = i + "===" + j;
//eval(str)
if(i === j) {
result = true;
} else {
result = false;
}
}
var after = Date.now();
console.log("Time: ", (after - before));
由于这些表达式可以是任何有效的 JS 表达式,我不能假设运算符。用户可以在表达式中自由使用任何类型的运算符(赋值、比较、算术、按位、逻辑、字符串或特殊运算符)。
例如 :
"{source.cn}==={target.cid} && {target.name} != 'XX'"
or
"({source.cn}==={target.cid} || {source.cn}/100 === 1 )&& {target.name} != 'XX'"
or anything else.
我不想编写自己的表达式解析器。
请提供帮助(不使用 eval) 1. 替代方法(但不是(new Function(expr)()) 2. 使用“if”而不是“eval”的某种方式将使我的代码非常快。就像上面的测试证明. 3. 任何其他在不影响要求的情况下使其快速的方法。(是的,目标对象中可能有多个匹配项)
提前致谢。