using underscore's “difference” method on arrays of objects

_.difference([], [])

this method works fine when i'm having primitive type data like

var a = [1,2,3,4];
var b = [2,5,6];

and the _.difference(a,b) call returns [1,3,4]

but in case i'm using object like

var a = [{'id':1, 'value':10}, {'id':2, 'value':20}];
var b = [{'id':1, 'value':10}, {'id':4, 'value':40}];

doesn't seem to work


try this on for size for finding the difference of an array of objects:

var test = [{a: 1},{b: 2}];
var test2 = [{a: 1}];

_.filter(test, function(obj){ return !_.findWhere(test2, obj); });

While the accepted answer is correct, and the other answers give good ideas as well, there is an additional option that's pretty easy to implement with underscore.

This solution relies on each object having a unique ID, but in many cases this will be true, and you can get the difference of two arrays of objects in just two lines of code.

Using underscore's "pluck" method, you can quickly construct an array of all of the ID's in your source set and the target set. From there, all of underscore's array methods will work, difference, union, intersection etc...

After the operation, it is trivial to obtain the list of objects from your source list that you desire. Here's an example:

Verbose:

var a = [{'id':1, 'value':10}, {'id':2, 'value':20}];
var b = [{'id':1, 'value':10}, {'id':4, 'value':40}];

var arr1 = _.pluck(a, "id");
var arr2 = _.pluck(b, "id");
var diff = _.difference(arr1, arr2);
var result = _.filter(a, function(obj) { return diff.indexOf(obj.id) >= 0; });

or, more concisely:

var diff = _.difference(_.pluck(a, "id"), _.pluck(b, "id"));
var result = _.filter(a, function(obj) { return diff.indexOf(obj.id) >= 0; });

Of course, this same technique can be extended for use with any of the array methods.