这可能比我想象的要简单得多,但我一直在试用javascript中的.map()和.filter()函数。我想要做的是使用.filter()创建一个数组,并为与第一个过滤器的谓词不匹配的元素创建另一个数组。到目前为止我所拥有的:
function test(array, predicate){
var filterTrue = array.filter(predicate);
var filterFalse = ??
// rest of method
}
有没有办法将与谓词不匹配的项目转储到filterFalse?可能不言而喻,但谓词通常是某种功能
编辑:顺便说一下,我试过了:
var filterFalse = array.filter(!predicate);
但是,由于我仍然试图理解的原因,这似乎并不起作用(对此的任何帮助也将非常感激)
答案 0 :(得分:6)
在这种情况下,您最好使用forEach
,但我会解答您为什么!predicate
无法正常工作的问题(以及如何制作之类的内容它也在下面。
首先,简单的forEach
解决方案:
Prosiac:
function test(array, predicate){
var filterTrue = [];
var filterFalse = [];
array.forEach(function(value) {
if (predicate(value)) {
filterTrue.push(value);
} else {
filterFalse.push(value);
}
});
// rest of method
}
更简洁:
function test(array, predicate){
var filterTrue = [];
var filterFalse = [];
array.forEach(function(value) {
(predicate(value) ? filterTrue : filterFalse).push(value);
});
// rest of method
}
顺便说一下,我试过了:
var filterFalse = array.filter(!predicate);
但是这似乎不适用于我仍在努力理解的原因
必须是:
var filterFalse = array.filter(function(entry) {
return !predicate(entry);
});
......这确实有效,但这意味着你要在数组中进行两次传递,并为每个元素调用谓词两次。这就是我推荐forEach
的原因:只需要一次遍历数组,每次只有一次调用谓词。
var filterFalse = array.filter(!predicate);
无法正常工作的原因是它采用predicate
变量,其中包含对函数的引用,并使用!
对其进行逻辑反转。非空对象引用(函数是对象)的逻辑反转版本为false
,因此您实际上将false
传递到filter
。
更完整:一元!
将其操作数强制转换为布尔值,然后返回相反的值false
true
和true
false
})。因此!predicate
会导致false
强制predicate
强制true
(也称为“真实”值)的任何值true
,并且会导致predicate
强制false
的{{1}}值(又名“假”值)。那么什么是“真实”和“虚假”的价值观? “假名”值为0
,""
,null
,undefined
,NaN
,当然还有false
; “truthy”值是所有其他值,包括所有非null
对象引用。
如果您使用谓词进行编程并想要一种说“非谓词”的方法并获得一个可以反转结果的函数,那么您可以这样做:
function not(predicate) {
return function() {
return !predicate.apply(this, arguments);
};
}
然后:
var filterFalse = array.filter(not(predicate));
not
函数的工作原理如下:它返回一个新函数,当调用它时,它将调用你给它的谓词函数,传递它被调用的this
值和所有的函数它被调用的参数(通过Function#apply
- spec | MDN),逻辑反转它从谓词中获得的返回值,然后返回该反转值。
但是,使用它需要两次通过数组。但是,有时使用高级抽象,这可能比forEach
解决方案更可取。
最后,如果你做了很多“或/或”事情,你当然可以做一个 的功能:
function divvyUp(array, predicate) {
var filterTrue = [], filterFalse = [];
array.forEach(function(value) {
(predicate(value) ? filterTrue : filterFalse).push(value);
});
return {
filterTrue: filterTrue,
filterFalse: filterFalse
};
}
答案 1 :(得分:3)
如果你想要被拒绝的值,那么让过滤器接受一个返回谓词倒数的函数:
function test(array, predicate) {
var filterTrue = array.filter(predicate);
var filterFalse = array.filter(not(predicate));
log(filterTrue, filterFalse);
}
function not(fn) {
return function () {
return !fn.apply(this, arguments);
}
}
function log(filterTrue, filterFalse) {
document.write('<pre> predicate true:' + JSON.stringify(filterTrue) + '</pre>');
document.write('<pre> predicate false: ' + JSON.stringify(filterFalse) + '</pre>');
}
var array = [1, 2, 3, 4, 5];
function isEven(value) {
return value % 2 === 0;
}
test(array, isEven);
答案 2 :(得分:2)
如果你还没有使用它们,就讨厌启动库,但是lodash有一个函数可以完成这个,称为partition。
_.partition([1, 2, 3], function(n) {
return n % 2;
});
// → [[1, 3], [2]]
_.partition([1.2, 2.3, 3.4], function(n) {
return this.floor(n) % 2;
}, Math);
// → [[1.2, 3.4], [2.3]]
创建一个元素数组,分为两组,第一组 包含元素谓词返回truthy,而第二个 其中包含元素谓词返回falsey。谓词是 绑定到thisArg并使用三个参数调用:(value,index | key, 集合)。
如果为谓词提供了属性名称,则创建_.property style callback返回给定元素的属性值。
如果还为thisArg提供了一个值,则创建_.matchesProperty 样式回调对具有匹配属性的元素返回true 值,否则为假。
如果为谓词提供了一个对象,则创建_.matches样式 对于具有该属性的元素,callback返回true 给定对象,否则为假。参数
- collection(Array | Object | string):要迭代的集合。
- [predicate = _。identity](函数|对象|字符串):每次迭代调用的函数。
- [thisArg](*):谓词的这种绑定。
醇>返回
(Array):返回分组元素的数组。
更多例子
var users = [
{ 'user': 'barney', 'age': 36, 'active': false },
{ 'user': 'fred', 'age': 40, 'active': true },
{ 'user': 'pebbles', 'age': 1, 'active': false }
];
var mapper = function(array) {
return _.pluck(array, 'user');
};
// using the `_.matches` callback shorthand
_.map(_.partition(users, { 'age': 1, 'active': false }), mapper);
// → [['pebbles'], ['barney', 'fred']]
// using the `_.matchesProperty` callback shorthand
_.map(_.partition(users, 'active', false), mapper);
// → [['barney', 'pebbles'], ['fred']]
// using the `_.property` callback shorthand
_.map(_.partition(users, 'active'), mapper);
// → [['fred'], ['barney', 'pebbles']]
答案 3 :(得分:0)
function test(array, predicate){
var filterTrue = array.filter(predicate);
var filterFalse = array.filter(function(data) { return !predicate(data); })
return { filterTrue: filterTrue, filterFalse: filterFalse }
}
mya = [ { id:1, desc: "one" }, { id:2, desc: "two" }, { id:3, desc: "three" }];
console.info(test(mya, function(data) { return data.id == 1; }))
&#13;
颠倒谓词。