Js - 使用运算符作为字符串评估数学表达式的替代方法
Js - Alternatives to eval mathematical expression with operator as string
我有一个库,它具有根据某些字段过滤对象的功能(每个字段都有特定类型 - 更多信息请参见 https://github.com/jy95/mediaScan/wiki)
最大的问题是处理来自多个来源的数字属性
// to handle number operations
export interface NumberExpressionObject {
operator: "==" | ">" | "<" | ">=" | "<=";
number: number;
}
// additional Properties
export interface AdditionalProperties {
type: AdditionalPropertiesType;
name: string;
value: boolean | string | string[] | number | NumberSearchSyntax;
}
例如:
expect((libInstance.filterTvSeries({
additionalProperties: [
{type: "number", name: "whateverFieldThatDoesn'tExist", value: "<50"},
{type: "number", name: "AnotherField", value: undefined},
{type: "number", name: "AnotherField2", value: "<=25"},
{type: "number", name: "AnotherField3", value: ">25"},
{type: "number", name: "AnotherField4", value: "==25"},
],
season: ">=4",
}))).toEqual(
new Map(),
);
每一个必须首先对应以下正则表达式:
const validExpression = /^(==|>|<|>=|<=)(\d+)$/;
然后将被这个函数求值:
function resolveExpression(property: string,
expressionObject: MediaScanTypes.NumberExpressionObject,
object: MediaScanTypes.TPN | MediaScanTypes.TPN_Extended): boolean {
return eval(`${object[property]}${expressionObject.operator}${expressionObject.number}`);
}
我想知道有什么更简洁的方法来做到这一点...请避免像 switch case 这样简单的答案:我测试了它,但在我的测试中它仍然比 eval 慢...
函数构造函数对我来说和 eval 一样..
我读过的以前的帖子:
Evaluating a string as a mathematical expression in JavaScript
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
...
为运算符实现函数
操作数 = {
'>': (a, b) => a > b,
'>=': (a, b) => a >= b
};
ops[expressionObject.operator](对象[属性],expressionObject.number)
如果表达式始终按预期有效。那么下面应该更快,因为没有解析。
eval(${object[property]}${expression}
)
你可以有一些从 operator
到 function
的映射
const ops = {'==':(a,b)=> a == b};
return ops[${expressionObject.operator}](${object[property]},${expressionObject.number})
我有一个库,它具有根据某些字段过滤对象的功能(每个字段都有特定类型 - 更多信息请参见 https://github.com/jy95/mediaScan/wiki)
最大的问题是处理来自多个来源的数字属性
// to handle number operations
export interface NumberExpressionObject {
operator: "==" | ">" | "<" | ">=" | "<=";
number: number;
}
// additional Properties
export interface AdditionalProperties {
type: AdditionalPropertiesType;
name: string;
value: boolean | string | string[] | number | NumberSearchSyntax;
}
例如:
expect((libInstance.filterTvSeries({
additionalProperties: [
{type: "number", name: "whateverFieldThatDoesn'tExist", value: "<50"},
{type: "number", name: "AnotherField", value: undefined},
{type: "number", name: "AnotherField2", value: "<=25"},
{type: "number", name: "AnotherField3", value: ">25"},
{type: "number", name: "AnotherField4", value: "==25"},
],
season: ">=4",
}))).toEqual(
new Map(),
);
每一个必须首先对应以下正则表达式:
const validExpression = /^(==|>|<|>=|<=)(\d+)$/;
然后将被这个函数求值:
function resolveExpression(property: string,
expressionObject: MediaScanTypes.NumberExpressionObject,
object: MediaScanTypes.TPN | MediaScanTypes.TPN_Extended): boolean {
return eval(`${object[property]}${expressionObject.operator}${expressionObject.number}`);
}
我想知道有什么更简洁的方法来做到这一点...请避免像 switch case 这样简单的答案:我测试了它,但在我的测试中它仍然比 eval 慢...
函数构造函数对我来说和 eval 一样..
我读过的以前的帖子:
Evaluating a string as a mathematical expression in JavaScript
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
...
为运算符实现函数
操作数 = { '>': (a, b) => a > b, '>=': (a, b) => a >= b };
ops[expressionObject.operator](对象[属性],expressionObject.number)
如果表达式始终按预期有效。那么下面应该更快,因为没有解析。
eval(
${object[property]}${expression}
)
你可以有一些从 operator
到 function
const ops = {'==':(a,b)=> a == b};
return ops[${expressionObject.operator}](${object[property]},${expressionObject.number})