简体   繁体   English

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

[英]How to get "unfiltered" array items?

Let's say I have an array which I filter by calling myItems.filter(filterFunction1) and get some items from it.假设我有一个数组,我通过调用myItems.filter(filterFunction1)过滤并从中获取一些项目。

Then I want to run another filtering function filterFunction2 against the remaining items which were not selected by filterFunction1 .然后我想对filterFunction2未选择的剩余项目运行另一个过滤函数filterFunction1

Is that possible to get the remaining items that were left out after calling a filtering function?在调用过滤函数后是否可以获取被遗漏的剩余项目?

You'd have to rerun the filter with an inverted predicate, which seems wasteful.您必须使用反向谓词重新运行过滤器,这似乎很浪费。 You should reduce the items instead and bin them into one of two bins:您应该reduce项目并将它们放入两个垃圾箱之一:

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

predicate here is the callback you'd give to filter .这里的predicate是你给filter的回调。

Unfortunately, there is no one-step solution based on filter .不幸的是,没有基于filter的一步解决方案。 Still the solution is a simple one-liner:解决方案仍然是一个简单的单行:

Here's an example这是一个例子

 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);

You could map an array of flags and then filter by the flags values.您可以映射一组标志,然后按标志值进行过滤。

 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);

You can achieve that using Array.reduce .您可以使用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: [] },
);

If you don't want to use reduce , you may want to iterate the array once and acquire the filtered and unfiltered items in a single shot, using a plain efficient for..of loop:如果您不想使用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);

There's a way more simple and readable way to do this:有一种更简单易读的方法来做到这一点:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM