如何获取“未经过滤”的数组项?

4
假设我有一个数组,我通过调用myItems.filter(filterFunction1)进行过滤并获取其中的一些项。
然后我想对由filterFunction1未选择的剩余项运行另一个过滤函数filterFunction2
是否可能获得在调用过滤函数后留下的剩余项呢?

如果您需要获取未过滤的项目,那么最好不要使用筛选器。因为这样可能无法一次性完成。 - briosheje
这更像是使用 reduce 和将项目分组到最终对象 { filtered: [...], unfiltered: [] } 中的工作。 - deceze
我实际上需要过滤和未过滤的项目,但分别放在数组中。 - Sergei Basharov
1
@SergeiBasharov,那么你可能想使用reduce或生成器来使数组只循环一次。 - briosheje
6个回答

10

你需要使用一个反向谓词重新运行过滤器,这似乎有些浪费。相反,你应该将项目 reduce 并将它们分别放入两个容器中:

const result = arr.reduce((res, item) => {
    res[predicate(item) ? 'a' : 'b'].push(item);
    return res;
}, { a: [], b: [] });

predicate 这里是你提供给 filter 的回调函数。


2

很不幸,没有基于filter的一步解决方案。但是解决方案只需一个简单的一行代码。

以下是一个例子:

(Note: "Original Answer" is translated as "最初的回答")

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

const filtered = arr.filter(x=>!!(x%2))

const remaining = arr.filter(x=>!filtered.includes(x))

console.log(filtered, remaining);


那是一种极其浪费的方法。 - deceze
4
@deceze 我还没有进行性能测试,但你可能是对的。尽管性能成本通常可以忽略不计,但这种方法可能比复杂的 reduce 调用更易读。 - connexo

0
你可以映射一个标志数组,然后按照标志值进行过滤。

const cond = v => !(v % 2);

var array = [1, 2, 3, 4, 5],
    flags = array.map(cond),
    result1 = array.filter((_, i) => flags[i]),
    result2 = array.filter((_, i) => !flags[i]);

console.log(result1);
console.log(result2);  


0

如果您不想使用reduce,您可以使用简单高效的for..of循环一次迭代数组并获取过滤和未过滤的项目:

function filterAndDiscriminate(arr, filterCallback) {
  const res = [[],[]];
  for (var item of arr) {
    res[~~filterCallback(item)].push(item);
  }
  return res;
}

const [unfiltered, filtered] = filterAndDiscriminate([1,2,3,4,5], i => i <= 3);
console.log(filtered, unfiltered);


0

有一种更简单和易读的方法来完成这个:

const array1 = []
const array2 = []
itemsToFilter.forEach(item => item.condition === met ? array1.push(challenge) : array2.push(challenge))

0
你可以使用 Array.reduce 实现这个。
const myItems = [...];

const { result1, result2 } = myItems.reduce(
  (result, item) => {
    if (filterFunc1(item)) {
      result.result1.push(item);
    } else if (filterFunc2(item)) {
      result.result2.push(item);
    }
    return result;
  },
  { result1: [], result2: [] },
);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接