Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

filter until some condition is met for the first time

Tags:

javascript

It's not a real world example, I over-simplified it. Giving this array:

const a = [1,2,3,4,5,6,7,8,4,5]; // Etc. Random numbers after.

I want to filter it to have only those matching a pattern (let's say greater than 3 for this trivial example) until something appends for the first time (let's say element is greater than 7)

So for this example, I just want: [4,5,6,7]. But with filter, I would have the trailing 4 and 5:

const a = [1,2,3,4,5,6,7,8,4,5].filter((v) => v > 3)
// returns: [4, 5, 6, 7, 8, 4, 5]

So I want to get item from an array and definitively stop after a condition. How can I filter then stop after the first time a condition is not met? (without for loop, I want to keep it "functional-like")

const a = [1,2,3,4,5,6,7,8,4,5,1,2,976,-1].awsome_function();
// returns: [4, 5, 6, 7, 8] because it stopped after the first 8.
like image 863
rap-2-h Avatar asked Mar 06 '17 14:03

rap-2-h


People also ask

What does the filter () method do when you use it?

The filter() method creates a new array filled with elements that pass a test provided by a function. The filter() method does not execute the function for empty elements. The filter() method does not change the original array.

Can we write if condition in filter?

To answer the question in the title: you can use if inside filter . filter accepts a function; in a classical function(arg) { ... } function, you can use if , obviously.

Does filter mutate the original array?

filter() does not mutate the array on which it is called. The range of elements processed by filter() is set before the first invocation of callbackFn .


2 Answers

You could use Array#some and combine both conditions.

var array = [1, 2, 3, 4, 5, 6, 7, 8, 4, 5],
    result = [];

array.some(a => (a > 3 && result.push(a), a > 7));
console.log(...result);

ES5

var array = [1, 2, 3, 4, 5, 6, 7, 8, 4, 5],
    result = [];

array.some(function (a) {
    if (a > 3) {
        result.push(a);
    }
    return a > 7;
});
console.log(...result);

A functional approach with filter and two constraints as function and a closure over a boolean value.

var array = [1, 2, 3, 4, 5, 6, 7, 8, 4, 5],
    filterFn = v => v > 3,
    stopFn = v => v > 7,
    filterBy = (fFn, sFn, go = true) => v => go && fFn(v) && (go = !sFn(v)),
    result = array.filter(filterBy(filterFn, stopFn));

console.log(...result);
like image 55
Nina Scholz Avatar answered Sep 30 '22 00:09

Nina Scholz


If you want to keep the functional style you can use this :

Array.prototype.filterUntil = function(predicate, stop){

  let shouldStop = false;

  return this.filter(function filter(value, index){
    if(stop(value)){
      shouldStop = true;
    }

    return shouldStop && predicate(value);
  });
}

In your case you can call it like this :

data.filterUntil(value => value > 3, value => value < 7)
like image 29
Rosmarine Popcorn Avatar answered Sep 29 '22 22:09

Rosmarine Popcorn