I have a library that have the feature of filtering objects based on some fields (each field has a specific kind of type - more info on https://github.com/jy95/mediaScan/wiki )
The biggest problem is to handle number properties from multiple source
// 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;
}
For example :
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(),
);
Each one must first corresponds the following regex :
const validExpression = /^(==|>|<|>=|<=)(\d+)$/;
and then will be eval by this function :
function resolveExpression(property: string,
expressionObject: MediaScanTypes.NumberExpressionObject,
object: MediaScanTypes.TPN | MediaScanTypes.TPN_Extended): boolean {
return eval(`${object[property]}${expressionObject.operator}${expressionObject.number}`);
}
I wonder what could be a more cleaner way to do that ... Please avoid easy answer like a switch case : I tested it but it was still slower in my tests than eval ...
Function constructor is for me the same thing than eval ..
Previous posts I read :
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
...
implement functions for operators
ops = { '>': (a, b) => a > b, '>=': (a, b) => a >= b };
ops[expressionObject.operator](object[property], expressionObject.number)
if the expression is always valid as expected. then following should faster as no parsing.
eval(${object[property]}${expression}
)
You can have some mapping from operator
to function
const ops = {'==':(a,b)=> a == b};
return ops[${expressionObject.operator}](${object[property]},${expressionObject.number})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With