silentmatt / expr-eval

Mathematical expression evaluator in JavaScript
http://silentmatt.com/javascript-expression-evaluator/
MIT License
1.18k stars 239 forks source link

How to transform object in mapper function #254

Open VincentdeWit94 opened 3 years ago

VincentdeWit94 commented 3 years ago

Would it be possible to create a mapper function that returns a new object with new values? Like we would do in JS:

.map((d) => ({a: d.alpha, b: d.beta})); Which would return: { a: 'alpha_val', b: 'beta_val' }

Thanks!

silentmatt commented 3 years ago

I'm not sure I understand the context for this. Can you add an example of how it would work with an expression?

VincentdeWit94 commented 3 years ago

Hi Matt,

Thanks! Yeah sure....

I see that your expression language supports the use of a mapping function through map(f, a). If you pass a regular array of objects through that map function and directly return a, it will return the inputted array of objects. What I would like to do, is to manipulate an attribute of the objects in the array, so let's say I have this array of objects:

[{ high: 1, low: 0 }, { high: 1, low: 0 }]

And I want to manipulate the high value in each object with a + 1, would I be possible to do that with the map function to return the array of objects with the manipulated objects? Like this:

f(o) = o.high+1; map(f, arrayOfObjects)

[{ high: 2, low: 0 }, { high: 2, low: 0 }]

Thanks!

silentmatt commented 3 years ago

Thanks, I see what you mean now. Support for objects right now is pretty limited, so I don't see a way to do that. It is possible with a JavaScript function that you pass into the expression (or add to the parser.functions object). I'll add an example below in case it helps. It would be useful to be able to do something similar "in-language" though, so I'll start thinking about how it would be implemented.

const parser = new Parser();
const arrayOfObjects = [{ high: 1, low: 0}, {high: 1, low: 0 }];
const scope = { arrayOfObjects: arrayOfObjects, f: (o) => ({ ...o, high: o.high + 1 }) };
parser.evaluate('map(f, arrayOfObjects)', scope);