【发布时间】:2016-07-25 03:29:01
【问题描述】:
我有一个对象数组,我想根据条件对其进行过滤和分组。困境来了,因为我有多个条件,并且希望将数组分成几个数组。第一个数组匹配第一个条件,第二个数组匹配第二个条件,...,最后一个数组包含所有不匹配任何条件的对象。
想到这个问题的第一个解决方案是几个 .filter 函数的形式......
var array = [{
name: 'X',
age: 18
}, {
name: 'Y',
age: 18
}, {
name: 'Z',
age: 20
}, {
name: 'M',
age: 20
}, {
name: 'W',
age: 5
}, {
name: 'W',
age: 10
}];
//objects with age 18
var matchedConditional1 = array.filter(function(x){
return x.age === 18;
});
//objects with age 20
var matchedConditional2 = array.filter(function(x){
return x.age === 20;
});
//objects with neither age 18 or 20
var matchedNoConditional = array.filter(function(x){
return (x.age !== 18 && x.age !== 20);
});
但这似乎是多余的,根本无法重用。
于是我修改了Brendan's答案上的函数,得到了这个。
Array.prototype.group = function(f) {
var matchedFirst = [],
matchedSecond = [],
unmatched = [],
i = 0,
l = this.length;
for (; i < l; i++) {
if (f.call(this, this[i], i)[0]) {
matchedFirst.push(this[i]);
} else if (f.call(this, this[i], i)[1]) {
matchedSecond.push(this[i]);
} else {
unmatched.push(this[i]);
}
}
return [matchedFirst, matchedSecond, unmatched];
};
var filteredArray = array.group(function(x){
return [x.age === 18, x.age === 20];
});
此方法返回一个包含 3 个数组的数组。第一个包含与第一个条件匹配的所有对象,第二个包含与第二个条件匹配的对象,最后一个包含与两者都不匹配的对象。
这种方法的问题在于它仅限于两个条件,因此只有三组对象。这种方法实际上适用于我的特定情况,因为我只有两个条件,但在需要两个以上的情况下是不可重用的。
我希望能够提供尽可能多的条件,并接收该数量的数组以及一个包含不属于任何组的对象的额外数组。
附言。输入和输出不需要是数组,但我认为这更有意义。该方法不必在 .filter 之后建模,它很可能是 .map 函数甚至是 .reduce。任何建议表示赞赏。
编辑:正如@slebetman 所建议的,如果答案允许代码可组合性,那就太好了。
【问题讨论】:
-
在目标函数中使用 switch case 尝试 array.map。在每种情况下,只需推送到相应的数组?
-
这种情况最好使用
array.forEach,因为它不是可以用链组合的操作 -
您只想修改代码还是愿意使用任何外部库?
-
我愿意接受任何允许我传递多个条件并根据条件对数组进行分组的解决方案。一个库就可以了,但 vanilla JS 可以提供更好的可重用性。
-
呃,只是创建一个
matched数组而不是使用索引变量?
标签: javascript arrays loops