expressions
npm install 3xpr>3xpr is an extensible expression evaluator and parser.
>
>Besides the operators, functions, variables, objects and arrays that are supported.
>
>It is possible to extend it with your own functions, operators, etc
- Constants, enums, number, string, datetime, variables, objects and array
- Arithmetic
, assignment
, comparison
, logical
and bitwise operators
- Number
, string
, datetime
, array
and nullable functions
- Conversion functions
- Arrow functions
- Group functions (distinct, first, last, min, max, sum and avg)
- Sets functions (union, intersection, difference and symmetric difference)
- Control flows flows
- Environment variables
- Extend
- Metadata
``javascript
import { expressions as exp } from '3xpr'
const context = {
name: 'Spain',
region: 'Europe',
phoneCode: '34',
timezones: [
{ name: 'Madrid', offset: 1, pos: { lat: 40.4165, log: -3.70256 } },
{ name: 'Ceuta', offset: 1, pos: { lat: 35.8883, log: -5.3162 } },
{ name: 'Canary', offset: 0, pos: { lat: 28.1248, log: -15.43 } }
]
}
const result = exp.eval('5(7+9)==(57+5*9)')
console.log(result)
// Output: true
// use context
exp.eval('toNumber(phoneCode) <= 30', context)
// false
// template
exp.eval('${name} belongs to ${region}', context)
// 'Spain belongs to Europe'
exp.eval('timezones.filter(p => substring(p.name,0,1)=="C")', context)
// ['{"name":"Ceuta","offset":1,"pos":{"lat":35.8883,"log":-5.3162}}'
// ,'{"name":"Canary","offset":0,"pos":{"lat":28.1248,"log":-15.43}}']
exp.eval('timezones.filter(p => p.offset == 1).sort(p => p.pos.lat).name', context)
// ['Ceuta','Madrid']
exp.eval('stringify(timezones.first(p => p.name == "Madrid").pos)', context)
// '{"lat":40.4165,"log":-3.70256}'
exp.eval('timezones.filter(p => p.pos.lat > 30 && p.pos.log > -4).pos.lat', context)
// [40.4165]
exp.eval('sort(timezones.name)', context)
// ['Canary','Ceuta','Madrid']
exp.eval('timezones[0].name', context)
// 'Madrid'
exp.eval('round(timezones.first(p=> p.name =="Madrid").pos.lat - timezones.first(p=> p.name =="Ceuta").pos.lat,2)', context)
// 4.55
exp.eval('timezones.each(p => p.pos={lat:round(p.pos.lat,2),log:round(p.pos.log,2)}).map(p=> stringify(p))', context)
// ['{"name":"Madrid","offset":1,"pos":{"lat":40.4,"log":-3.7}}'
// ,'{"name":"Ceuta","offset":1,"pos":{"lat":35.9,"log":-5.3}}'
// ,'{"name":"Canary","offset":0,"pos":{"lat":28.1,"log":-15.45}}']
exp.eval(
list = [1, 2, 3, 4, 5, 6, 7, 8, 9];
total = 0;
for (i = 0; i < list.length(); i += 1) {
total += list[i];
}, context)
console.log(context.total)
// 45
exp.eval(
while (p=timezones.pop()) {
console(p);
}, context)`
// outputs:
// {"name":"Canary","offset":0,"pos":{"lat":28.1,"log":-15.45}}
// {"name":"Ceuta","offset":1,"pos":{"lat":35.9,"log":-5.3}}
// {"name":"Madrid","offset":1,"pos":{"lat":40.4,"log":-3.7}}
You can extend the library by adding enums, constants, formats, operators, and functions.
To do this, use the following functions:
- AddConstant: Adds a constant to the library.
- AddEnum: Adds an enumeration to the library.
- AddFormat: Adds a format to the library.
- AddOperator: Adds an operator to the library.
- AddFunction: Adds a function to the library.
`typescript
import { expressions as exp } from '3xpr'
const CryptoJS = require('crypto-js')
exp.addFunction(
'encrypt(value:string):string',
(value: string, key:string):string => CryptoJS.AES.encrypt(value, key).toString(),
{ description: 'Encrypt a string' }
)
exp.addFunction(
'decrypt(value:string):string',
(value: string, key:string):string => CryptoJS.AES.decrypt(value, key).toString(CryptoJS.enc.Utf8),
{ description: 'Decrypt a string' }
)
``
Full documentation is available in the Wiki.