In the example code below I want to filter numbersArray based on different intervals. An interval is defined by a combination of 2 arrays with the lower and upper bound of said interval. How do I identify matches or non-matches like below?

const numbersArray = [1,2,3,4,5,6,7,8,9,10]; const lowerBound = [1, 4, 8]; const higherBound = [3, 6, 10];

If the code works the following test should return true:

matches == [2, 5, 9]; nonmatches == [1, 3, 4, 6, 7, 8, 10];

**Assume the arrays contains more than 1000 items and that the numbers doesn’t follow any pattern.**

Below is a less readable but more realistic scenario.

let numbersArray = []; let lowerBound = []; let higherBound = []; for (let i = 0; i< 1000; i++){ numbersArray.push(i); } for(let i = 0; i < 100; i++) { lowerBound.push(i * 10); higherBound.push((i * 10) + Math.random() * 10); }

## Answer

I’m going to assume that we can change the data structure a little bit because this is quite awkward to work with:

const lowerBound = [1, 4, 8]; const higherBound = [3, 6, 10];

If the elements at the same indexes are meant to be together then let’s just do that:

const bound = [[1, 3], [4, 6], [8, 10]];

Will come to `bound`

later.

Now let’s build a curried function that validates `n`

if `a < n && n < b`

:

const between = (a, b) => n => a < n && n < b; const x = between(1, 3); const y = between(4, 6); x(1); // false x(2); // true y(1); // false y(5); // true

Now let’s build another curried function that validates `n`

if at least one function returns `true`

:

const or = (...fns) => n => fns.some(fn => fn(n)); const check = or(x, y); check(1); // false check(2); // true check(5); // true

We will now transform `bound`

into an *or* function after we transformed each pair into a *between* function:

const bound = [[1, 3], [4, 6], [8, 10]]; const check = or(...bound.map(([a, b]) => between(a, b)));

`check`

is now a function that takes an `n`

and returns `true`

if `n`

is between 1 and 3 or between 4 and 6, …

const between = (a, b) => n => a < n && n < b; const or = (...fns) => n => fns.some(fn => fn(n)); const bound = [[1, 3], [4, 6], [8, 10]]; const check = or(...bound.map(([a, b]) => between(a, b))); const [nomatch, match] = [1,2,3,4,5,6,7,8,9,10].reduce( (acc, n) => (acc[+check(n)].push(n), acc), [[], []]); console.log(`match: [${match}]`); console.log(`no match: [${nomatch}]`);