如何限制10个结果array.filter?

Raz*_*Raz 6 javascript

我有一个大数组,我想进行自动完成搜索,但是我只想显示10个结果,所以在找到10个结果时停止对数组进行迭代。我做了这个:

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

它有效,但我不知道如何在array.filter达到所需限制时停止。

Ice*_*kle 9

基本上你可以使用一个生成器函数,它可以通过一个自制的限制来停止,就像下面的函数

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
Run Code Online (Sandbox Code Playgroud)

所以当它作为参数达到 maxSize 后就会停止,为了方便地将其返回到数组中,可以使用 Array.from,它将迭代生成器函数的迭代器

  • 这是我想要的解决方案。现在,你可以用一个点差来简写 `Array.from(someIterable)`:`[...someIterable]` (2认同)

Tit*_*tus 9

您可以使用另一个变量来跟踪到目前为止与条件匹配的项目数量,并在达到限制后始终返回 false。下面是一个例子:

const arr = [1,0,2,0,3,0,4,5,6,7,8,9,10,11,12,13,14];
const filtered = arr.filter(function(item) {
  if (this.count < 10 && item > 0) {
    this.count++;
    return true;
  }
  return false;
}, {count: 0});

console.log(filtered);
Run Code Online (Sandbox Code Playgroud)

在这里,我使用一个对象{count: 0}作为回调函数的上下文。您可以从这里了解更多信息Array.filter

  • @VLAZ 是的,它在那里,但我不经常使用它,因为它需要一个普通函数,它不适用于箭头函数。 (4认同)
  • 聪明的。我一直忘记`.filter`(和`.map` 等)中的第二个参数。 (2认同)

Nin*_*olz 6

您可以交出一个计数器并省略任何其他过滤值。

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);
Run Code Online (Sandbox Code Playgroud)

将 Icepickle 的答案的想法提前一点,循环查找下一个有效项目并产生这个。

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));
Run Code Online (Sandbox Code Playgroud)

  • 这也将遍历整个数组 (3认同)
  • 我能问一下为什么你不使用`array.filter(...).slice(0,max)`? (2认同)
  • @MaheerAli 将遍历整个数组。如果你有 100 万个项目,然后过滤到 90 万个,只取前 10 个,这对处理能力来说是巨大的浪费。 (2认同)

adi*_*iga 6

你不能breakArray.prototype.filter方法。它将循环遍历每个元素。您可以使用一个简单的for循环,并在找到 10 个项目时中断

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