1

I've already looked into this for a couple of days and feel like I'm missing an obvious implementation here.

(see lodash Filter collection using array of values for something similar).

What I want to do is take a collection of items that a user already has, and then use that to filter from the entire list of items. There are number of ways to iterate through the list and create a new collection and return it, or a way to potentially create a mixin that does this, but I was curious if there's just a chain of one-liners or a concept I'm missing. The goal is to do a deep comparison of each object in the collection to determine equivalence.

Here's the example (jsFiddle here: http://jsfiddle.net/kxLt534f/)

var collection = [
    {id:1, name:'one'},
    {id:2, name:'two'},
    {id:3, name:'three'}
];

var filter = [
    {id:2, name:'two'}
];

// what I want to be able to do
// var result = _.someFilterMethod(collection,filter);

// what it looks liked I'll have to do
var filtered = _.select(collection, function(c){
  var same = false;
  _.forEach(filter,function(f) {
     same = _.isEqual(f,c);
  });
  return !same;
});

console.warn(filtered); // output is : [{id:1,name:'one',id:3,name:'three'}]

There's gotta be a nicer way to do this, but I for the life of me can't see it. Any suggestions would be appreciated!

Community
  • 1
  • 1
NateDSaint
  • 1,524
  • 2
  • 16
  • 35
  • 1
    Have a look at this question http://stackoverflow.com/questions/8672383/how-to-use-underscores-intersection-on-objects – Alberto Zaccagni Nov 23 '15 at 17:04
  • That's an interesting answer, I suppose I didn't think about it in terms of intersection, though this is the inverse of that. Let me look through and see if I can piece something together, but it ultimately seems like a mixin based on the above is the same answer that they're coming up with there. – NateDSaint Nov 23 '15 at 17:34
  • What's the expected output? Can you give an example where there's more than one item in the `filter` array? – Adam Boduch Nov 23 '15 at 18:35
  • Sorry for the delay, Thanksgiving here in the US so I avoided computers for a bit. I'll update the question to be more specific. – NateDSaint Nov 30 '15 at 17:39
  • I'm leaving this here because I think this is a good use case that someone may come up against, but it's better big O and probably more likely to yield good results to create an array of IDs using pluck, then filter out the ones that match that ID. The weakness there is that others might want a true deep comparison. – NateDSaint Nov 30 '15 at 17:45

1 Answers1

2

The function _.intersectionWith was added in lodash 4.0, it should do exactly what you want. Use it as follows:

var collection = [
    {id:1, name:'one'},
    {id:2, name:'two'},
    {id:3, name:'three'}
];

var filter = [
    {id:2, name:'two'}
];


// _.isEqual performs a deep comparison
_.intersectionWith(collection, filter, _.isEqual) // [{"id":2,"name":"two"}]
Martin Foley
  • 36
  • 1
  • 2