'How to limit for 10 results the array.filter?

I have big array, I want to make an autocomplete search, but I want to display only 10 results, so stop iterating through the array by the time there were found 10 results. I have made this:

let items = array.filter(r => r.indexOf(term)!=-1);
console.log(items.length) // lots of items, need to be limited to 10

It works but I don't know how to stop the array.filter by the time it reaches the desired limit.



Solution 1:[1]

Basically you can use a generator function, which can be stopped by a self made limit, like in the below function

function *filter(array, condition, maxSize) {
  if (!maxSize || maxSize > array.length) {
    maxSize = array.length;
  }
  let count = 0;
  let i = 0;
  while ( count< maxSize && i < array.length ) {
    if (condition(array[i])) {
      yield array[i];
      count++;
    }
    i++;
  }
}

const array = [1, 2, 3, 4, 5, 6, 7, 8, 9];

console.log( Array.from( filter(array, i => i % 2 === 0, 2 ) ) ); // expect 2 & 4

So it will stop after it reaches maxSize as a parameter, and to easily return it into an array, you can use Array.from, which will iterate the iterator of the generator function

Solution 2:[2]

You could hand over a counter and omit any other values for filtering.

const
    filter = v => v % 2,
    filterMax = (fn, c) => x => c && fn(x) && c--,
    max = 3,
    array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    result = array.filter(filterMax(filter, max));

console.log(result);

Taking the idea of Icepickle's answer a bit ahead with a loop for finding the next valid item and yield this one.

function* filterMax(array, cb, count) {
    var i = 0;
    while (count) {
        while (i < array.length && !cb(array[i])) i++;
        if (i >= array.length) return;
        yield array[i++];
        count--;
    }
}

const
    filter = v => v % 2,
    max = 3,
    array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(...filterMax(array, filter, max));

Solution 3:[3]

var data = ["1","2","3","4","5","6","7","8","9","10","11","12","13","14"]

var limited = data.filter((val,i)=>i<10)
console.log(limited)

Solution 4:[4]

You can't break from Array.prototype.filter method. It will loop over every element. You can use a simple for loop and break when 10 items are found

const items = []
for (const value of array) {
  if (value.includes(term))
    items.push(value)
  if (items.length === 10)
    break;
}

Solution 5:[5]

Just for the trick :

EDIT : To clarify this code will pick the 10 first even number of the list

let array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30];

const result = array.reduce((temp, value) => {
  if(value%2==0 && temp.length<10)
    temp.push(value);
  return temp;
}, []);

console.log(result);

Solution 6:[6]

I wrote a library that's handy for this sort of thing.

Here's how I'd find the first 100 numbers that start with the character "1"

const {blinq, range} = window.blinq;

//create a large array of strings to search
const arrToBeSearched = range(0,10000)
  .select(x => `${x}`)
  .toArray()

const query = blinq(arrToBeSearched)
  .where(x => x.startsWith("1"))
  .takeWhile((x, i) => i < 100)

const result = [...query] //no calculation until we materialize on this line

console.log(result)
<script src="https://cdn.jsdelivr.net/npm/blinq"></script>

Solution 7:[7]

I know its a bit late, but here's for the new comers!

// we'll create a function which will take two arguments
// first argument would be your original array which your want to filter from
// second argument would be the number of results you want the filter to return

const limitedArray = (originalArray, limit) => {
    let newArray = [];
    for (let item of originalArray) {
      if (newArray.length >= limit) break;
      //your code here
      //in my case i'll jush push in to the array
      newArray.push(item)
    }
    return newArray;
  };
  
//---------------->ignore v<-------------------  

//the above function would return an array so in other words we can see this function as an array
const array = [1, 2, 3, 4, 5, 6, 'cascas', 'ascasc', 9, 10, 'ascs'];

console.log(limitedArray(array, 4));
//similarly
limitedArray(array, 4).forEach(item => {
  console.log(item)
})
  
  

Solution 8:[8]

You can do this just simple add .Slice(0,NO_OF_ELE_WANT) eg. finding first two even no

[1,2,3,4,5,6,7,8,9,10].filter((e)=> e%2==0).slice(0,2)

Answer : let items = array.filter(r => r.indexOf(term)!=-1).slice(0,10);

Solution 9:[9]

You can define your custom method on Array.prototype which will take 2 arguments. A callback and a max elements that result array will contain.

The code below gets the first 3 odd numbers from array.

function filterUpto(callback,max){
  let len = this.length
  let res = [];
  let i = 0;
  while(res.length < max && i < len){
    if(callback(this[i],i,this)) res.push(arr[i])
    i++
  }
  return res;
}

Object.defineProperty(Array.prototype,'filterUpto',{
  value:filterUpto
})

let arr = [1,2,3,4,5,6,7,8,9,10];
console.log(arr.filterUpto(x => x % 2,3)); //first three odd numbers

Solution 10:[10]

Here is another possible solution, pretty straightforward, using Array.from:

const arr = [
  "foo",
  "bar",
  "foobar",
  "baz",
  "foobaz",
  "artefact",
  "mortar",
  "bar",
  "arity",
  "mark",
  "car",
  "dare",
  "arbitrary",
  "tar",
  "jar",
  "war",
];

const filterWithLimit = (arr, value, length) =>
  Array.from(
    { length },
    function () {
      return arr
        .slice(this.index++)
        .find((option, i) => (this.index += i, option.includes(value)));
    },
    { index: 0 }
  );

console.log(filterWithLimit(arr, "ar", 10));

Solution 11:[11]

Here is a short solution which doesn't continue searching after the limit is reached:

function filter_n(array, limit, test) {
   let ret = []
   array.find((x)=> test(x) && ret.push(x)>=limit )
   return ret
}
  • when test(x) is true, it calls ret.push(x) (which adds x to ret and outputs the length of ret)
    • then, once ret's length is >= limit, the inner function returns true, and find stops looping because it "found" a result

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Icepickle
Solution 2
Solution 3
Solution 4 adiga
Solution 5 PopHip
Solution 6 spender
Solution 7 Waleed Tariq
Solution 8 Rajan Kumar
Solution 9
Solution 10
Solution 11 12Me21