Js - 使用运算符作为字符串来评估数学表达式的替代方法

时间:2018-04-10 01:46:06

标签: javascript node.js typescript eval

我有一个库,它具有基于某些字段过滤对象的功能(每个字段都有一种特定的类型 - 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}`);
}

我想知道什么是更清洁的方法呢...请避免简单的回答,如开关案例:我测试了它,但它在我的测试中仍然比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
...

2 个答案:

答案 0 :(得分:1)

  1. 为运营商实施功能

    ops = {     '&gt;':( a,b)=&gt; a&gt; b,     '&gt; =':( a,b)=&gt; a&gt; = b };

    ops [expressionObject.operator](object [property],expressionObject.number)

  2. 如果表达式始终按预期有效。然后跟随应该更快,因为没有解析。

    的eval(${object[property]}${expression}

答案 1 :(得分:1)

您可以拥有从operatorfunction

的映射
const ops = {'==':(a,b)=> a == b};
return ops[${expressionObject.operator}](${object[property]},${expressionObject.number})