我想使用属性值数组过滤集合。给定一组ID,返回具有匹配ID的对象。是否有使用lodash
/ underscore
的快捷方法?
var collections = [{ id: 1, name: 'xyz' },
{ id: 2, name: 'ds' },
{ id: 3, name: 'rtrt' },
{ id: 4, name: 'nhf' },
{ id: 5, name: 'qwe' }];
var ids = [1,3,4];
// This works, but any better way?
var filtered = _.select(collections, function(c){
return ids.indexOf(c.id) != -1
});
答案 0 :(得分:59)
如果你要使用这种模式,你可以创建一个如下所示的mixin,但它没有做与原始代码完全不同的任何事情。它只是让它更适合开发人员。
_.mixin({
'findByValues': function(collection, property, values) {
return _.filter(collection, function(item) {
return _.contains(values, item[property]);
});
}
});
然后你可以像这样使用它。
var collections = [
{id: 1, name: 'xyz'},
{id: 2, name: 'ds'},
{id: 3, name: 'rtrt'},
{id: 4, name: 'nhf'},
{id: 5, name: 'qwe'}
];
var filtered = _.findByValues(collections, "id", [1,3,4]);
更新 - 以上答案陈旧且笨重。请使用answer from Adam Boduch获得更优雅的解决方案。
_(collections)
.keyBy('id') // or .indexBy() if using lodash 3.x
.at(ids)
.value();
答案 1 :(得分:16)
我们也可以像这样过滤
var collections = [{ id: 1, name: 'xyz' },
{ id: 2, name: 'ds' },
{ id: 3, name: 'rtrt' },
{ id: 4, name: 'nhf' },
{ id: 5, name: 'qwe' }];
var filtered_ids = _.filter(collections, function(p){
return _.includes([1,3,4], p.id);
});
console.log(filtered_ids);
答案 2 :(得分:6)
我喜欢jessegavin's回答,但我使用lodash-deep对其进行了深入的属性匹配。
var posts = [{ term: { name: 'A', process: '123A' } },
{ term: { name: 'B', process: '123B' } },
{ term: { name: 'C', process: '123C' } }];
var result = _.filterByValues(posts, 'term.process', ['123A', '123C']);
// results in objects A and C to be returned
_.mixin({
'filterByValues': function(collection, key, values) {
return _.filter(collection, function(o) {
return _.contains(values, resolveKey(o, key));
});
}
});
function resolveKey(obj, key) {
return (typeof key == 'function') ? key(obj) : _.deepGet(obj, key);
}
如果您不信任lodash-deep,或者您希望支持名称中包含点的属性,那么这是一个更具防御性且更强大的版本:
function resolveKey(obj, key) {
if (obj == null || key == null) {
return undefined;
}
var resolved = undefined;
if (typeof key == 'function') {
resolved = key(obj);
} else if (typeof key == 'string' ) {
resolved = obj[key];
if (resolved == null && key.indexOf(".") != -1) {
resolved = _.deepGet(obj, key);
}
}
return resolved;
}
答案 3 :(得分:1)
我注意到其中许多答案已过时或包含Lodash文档中未列出的辅助功能。接受的答案包括已弃用的函数_.contains
,应予以更新。
所以这是我的ES6答案。
_.mixin( {
filterByValues: ( c, k, v ) => _.filter(
c, o => _.indexOf( v, o[ k ] ) !== -1
)
} );
并且这样调用:
_.filterByValues(
[
{
name: 'StackOverflow'
},
{
name: 'ServerFault'
},
{
name: 'AskDifferent'
}
],
'name',
[ 'StackOverflow', 'ServerFault' ]
);
// => [ { name: 'StackOverflow' }, { name: 'ServerFault' } ]
答案 4 :(得分:1)
这些答案对我不起作用,因为我想过滤一个非唯一的值。如果您将groupBy
更改为_(collections)
.groupBy(attribute)
.pick(possibleValues)
.values()
.flatten()
.value();
,则可以通过。
pick
我最初使用的是丢弃内容,因此我使用omit
切换了{{1}}。
感谢Adam Boduch作为起点。
答案 5 :(得分:1)
这对我很有用:
let output = _.filter(collections, (v) => _.includes(ids, v.id));