lodash使用数组值过滤集合

我想过滤使用数组属性值的集合。 给定一个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 }); 

如果你打算使用这种模式,你可以像下面这样创build一个mixin,但是它不会做任何与你原来的代码不同的fundement。 这只是让开发更友好。

 _.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]); 

更新 – 这个答案是古老和笨重的。 请使用Adam Boduch的答案来获得更加优雅的解决scheme。

 _(collections) .keyBy('id') // or .indexBy() if using lodash 3.x .at(ids) .value(); 

使用indexBy()和at()的简明lodash解决scheme。

 _(collections) .indexBy('id') .at(ids) .value(); 

我们也可以这样过滤

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

我喜欢jessegavin的回答,但我使用深度为深度的属性匹配扩大了它。

 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 

的jsfiddle

 _.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深层的,或者你想要支持名字中有点的属性,这里有一个更加防御和强大的版本:

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

我注意到许多这些答案已经过时,或包含Lodash文档中未列出的辅助function。 接受的答案包括已弃用的函数_.contains ,应该更新。

所以这是我的ES6答案。

基于Lodash v4.17.4

 _.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' } ] 

这些答案不适合我,因为我想过滤一个非唯一的值。 如果你把keyBy改成keyBy ,你可以通过。

 _(collections) .groupBy(attribute) .pick(possibleValues) .values() .flatten() .value(); 

我最初的用途是放弃东西,所以我转而pick omit

感谢Adam Boduch的出发点。