Collection of the lodash collection using an array of values

I would like to filter the collection using an array of property values. Given an array of identifiers, return objects with the corresponding identifiers. Is there any quick access method using 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 }); 
+46
Jun 22 '13 at 14:23
source share
6 answers

If you intend to use this type of template, you can create a mixin as shown below, but it does nothing fundamentally different from your source code. It just makes it more convenient for developers.

 _.mixin({ 'findByValues': function(collection, property, values) { return _.filter(collection, function(item) { return _.contains(values, item[property]); }); } }); 

Then you can use it like this.

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

Update . This answer is old and awkward. Please use the answer from Adam Boduh for a more elegant solution.

 _(collections) .keyBy('id') // or .indexBy() if using lodash 3.x .at(ids) .value(); 
+57
Sep 16 '13 at 14:49
source share

A short lodash solution that uses indexBy () and at () .

 _(collections) .indexBy('id') .at(ids) .value(); 
+34
Nov 23 '15 at 18:40
source share

We can also filter as

 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); 
+12
Jun 15 '16 at 11:23
source share

I like jessegavin's answer , but I expanded it using lodash-deep to deeply map properties.

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

If you do not trust lodash-deep or want to support properties that have dots in their names, here is a more secure and reliable version:

 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; } 
+6
Jan 27 '15 at 14:54
source share

I noticed that many of these answers are deprecated or contain helper functions not listed in the Lodash documentation. The accepted answer includes the deprecated _.contains function and needs to be updated.

So here is my ES6 answer.

Based on Lodash v4.17.4

 _.mixin( { filterByValues: ( c, k, v ) => _.filter( c, o => _.indexOf( v, o[ k ] ) !== -1 ) } ); 

And called as such:

 _.filterByValues( [ { name: 'StackOverflow' }, { name: 'ServerFault' }, { name: 'AskDifferent' } ], 'name', [ 'StackOverflow', 'ServerFault' ] ); // => [ { name: 'StackOverflow' }, { name: 'ServerFault' } ] 
0
Oct 26 '17 at 13:41 on
source share

These answers did not work for me because I wanted to filter out a non-standard value. If you change keyBy to groupBy , you can go through.

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

My initial use was to reset things, so I disabled pick with omit .

Thanks to Adam Boduh for the starting point.

0
Nov 20 '17 at 17:25
source share



All Articles