Nas Nas - 9 months ago 36
Javascript Question

using underscore's “difference” method on 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
call returns

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

Answer Source

Reason is simply that object with same content are not same objects e.g.

var a = [{'id':1, 'value':10}, {'id':2, 'value':20}]; 
a.indexOf({'id':1, 'value':10})

It will not return 0 but -1 because we are searching for a different object

See the source code, _.difference uses _.contains

_.difference = function(array) {
  var rest = concat.apply(ArrayProto,, 1));
  return _.filter(array, function(value){ return !_.contains(rest, value); });

and _.contains ultimately uses indexOf hence will not find objects unless they point to same object.

You can improve the underscore _.contains by looping through all items and calling a compare callback, which you should be able to pass to difference or contains function or you can check this version which improves contains methods