如何获取"unfiltered"数组项目?



假设我有一个数组,我通过调用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))

最新更新