如何在使用javascript的过滤器时获取排除的元素



Javascript的filter返回数组,其中所有元素都通过了测试。

如何在不重新运行测试的情况下轻松获得所有未通过测试的元素,但反过来呢?即使你必须再次运行测试,如何做是最好的方法。

let arr; // this is the array on which the filter will be run [SET ELSEWHERE]
let fn; // The filter function [SET ELSEWHERE]
let goodElements; // This will be the new array of the good elements passing the test
let badElements; // This will be the new array of the elements failing the test
goodElements = arr.filter(fn);
// SO HOW IS badElements set????

badElements是如何设置的?

如果不想进行两次迭代,可以使用for循环和三元运算符:

let arr = [1, 2, 3];
let fn = (e) => e % 2 == 0;
let goodElements = [];
let badElements = [];
for(const e of arr) (fn(e) ? goodElements : badElements).push(e);
console.log(goodElements);
console.log(badElements);

否则,只需使用!运算符反转条件:

let arr = [1, 2, 3];
let fn = (e) => e % 2 == 0;
let goodElements;
let badElements;
goodElements = arr.filter(fn);
badElements = arr.filter(e => !fn(e));
console.log(goodElements);
console.log(badElements);

不要使用filter()。如果您想将数据划分为两个数组,请自己动手。

function partition(array, fn) {
let goodArray = [],
badArray = [];
array.forEach(el => {
if (fn(el)) {
goodArray.push(el);
} else {
badArray.push(el);
}
});
return [goodArray, badArray];
}
let [goodElemements, badElements] = partition(arr, fn);

您也可以使用reduce()

function partition(array, fn) {
return array.reduce(acc, el => {
if (fn(el)) {
acc[0].push(el);
} else {
acc[1].push(el);
}
}, [[],[]]);
}
let [goodElemements, badElements] = partition(arr, fn);

如果您想严格使用Array.filter并且只使用一个循环,那么可以考虑以下内容:

UPD:基于@AlvaroFlañoLarrondo的评论,在当前方法中添加了外部条件函数。

// Array of elements
const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
// External filter method
const fn = e => e.length > 6;
// Define empty bad array
const bad = [];
// Define good array as result from filter function
const good = words.filter(word => {
// In filter condition return good values
if(fn(word)) return word;
// And skip else values by just pushing them
// to bad array, without returning
else bad.push(word);
});
// Results
console.log(good);
console.log(bad);

您可以使用reduce根据谓词将数组拆分为两个数组,如本例所示:

const arr = [1, 0, true, false, "", "foo"];
const fn = element => !element;
const [goodElements, badElements] = arr.reduce(
([truthies, falsies], cur) =>
fn(cur) ? [truthies, [...falsies, cur]] : [[...truthies, cur], falsies],
[[], []]
);
console.log(goodElements, badElements);

我看到两条可能的路线:

// in this case, if it's not in `goodElements`, it's a bad 'un
badElements = arr.filter( el => !goodElements.includes(el) );

或者这个:

// we don't **know** if fn needs the optional parameters, so we will
//  simply pass them. If it doesn't need 'em, they'll be ignored.
badElements = arr.filter( (el, idx, arr) => !fn(el, idx, arr) );
const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
const fn = (x) => x % 2 === 0
const removeItems = (array, itemsToRemove) => {
return array.filter(v => {
return !itemsToRemove.includes(v);
});
}

const goodElements = arr.filter(fn)
console.log(goodElements) // [ 0, 2, 4, 6, 8 ]
const badElements = removeItems(arr, goodElements)
console.log(badElements) // [ 1, 3, 5, 7, 9 ]

最新更新