假设我有一个数组,我通过调用myItems.filter(filterFunction1)
进行过滤并从中获取一些项目。
然后我想运行另一个过滤功能filterFunction2
针对未被filterFunction1
选择的其余项目。
是否可以获取调用过滤函数后遗漏的剩余项?
您必须使用反转谓词重新运行过滤器,这似乎很浪费。您应该改为reduce
这些物品,并将它们装箱到两个垃圾箱之一中:
const result = arr.reduce((res, item) => {
res[predicate(item) ? 'a' : 'b'].push(item);
return res;
}, { a: [], b: [] });
predicate
这是您给filter
的回调。
不幸的是,没有基于filter
的一步解决方案。解决方案仍然是简单的单行:
下面是一个示例
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);
您可以映射一个标志数组,然后按标志值进行筛选。
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);
您可以使用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: [] },
);
如果您不想使用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);
有一种更简单和可读的方法可以做到这一点:
const array1 = []
const array2 = []
itemsToFilter.forEach(item => item.condition === met ? array1.push(challenge) : array2.push(challenge))