How to do a comparaison from an array of comparators ['<', '<=', '>', '>=']?

Viewed 86

UPDATE

The idea here is to filter out numbers say less than 10 or (less than or equal to 10) or greater that 10 or (greater than or equal to 10).

So as the user inputs a value like this show me all nums less than or equal to 10 (the input will be <=10 )

The idea is to filter out numbers from an array using comparisons, when a particular one is matched

REM v is supposed to be like this <5 or <10 or <=3 or <=2 or >5 or >=6 and so on...

nums.filter(num => {
    return comparisions.map(operation => {
        if (v.startsWith('>'))
        return num > parseInt(v.replace('>', '').trim());

        if (v.startsWith('>='))
        return num >= parseInt(v.replace('>=', '').trim());

        if (v.startsWith('<='))
        return num <= parseInt(v.replace('<=', '').trim());

        if (v.startsWith('<'))
        return num < parseInt(v.replace('<', '').trim());
    })
})

instead of above repetition how can I consolidate it in to the following function?



const comparisions = ['<', '<=', '>', '>=']

const nums = [3, 2, 1, 5, 6, 10]
// here I've shown only few a numbers for simplicity. In real it is a big array of nos.

nums.filter(num => {
    return comparisions.map(operation => {
        if (v.startsWith(operation))
        return num operation parseInt(v.replace(operation, '').trim());
    })
})
//example v = '<=10'

UPDATE no eval()s please. I'm not a fan of evals.

3 Answers

Build an object map of operations to comparison functions. Use it to filter.

Assumes v always matches "[matches to a key in comparisons][digits]"

const comparisions = {
  '<':  (x, y) => x < y,
  '<=': (x, y) => x <= y,
  '>':  (x, y) => x > y,
  '>=': (x, y) => x >= y
}
// you could also build functions that evaluate using eval or Function constructor based on the key(< or <= etc) provided

const nums = [3, 2, 1, 5, 6, 10]

v = "<=3"

console.log(
  nums.filter(num => {
    const [, op, n] = v.match(/^(.*?)(\d+)$/)
    return comparisions[op](num, n)
  })
)

You can use eval like this :

let cmp = (input,op)=>(`${op}${input}`);
console.log(eval(`${1}${cmp(3,'<')}`)); // is 1 < 3 ?

You could use a package like jexl, that can be used to evaluate expressions, but it could be an "overkill" solution.

But using jexl, for example, you would only have to do this:

nums.filter(num => jexl.evalSync(`${num}${v}`))
Related