Using Underscore's "Difference" Method on Arrays of Objects

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

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 http://underscorejs.org/underscore.js, _.difference uses _.contains

_.difference = function(array) {
var rest = concat.apply(ArrayProto, slice.call(arguments, 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

Difference between two arrays of objects coffeescript using underscore js

Do you want to use the difference function of underscore? You can do this:

_.difference([1, 2, 3, 4, 5], [5, 2, 10])

this works in coffeescript.

EDIT

Using an array of objects and comparing the id property

arrayOne = [{id: 1}, {id: 2}]
arrayTwo =[{id: 2}, {id: 3}]

_.select arrayOne, (item) ->
!_.findWhere(arrayTwo, {id: item.id})

How to get the difference between two arrays of objects in JavaScript

Using only native JS, something like this will work:

const a = [{ value:"0", display:"Jamsheer" }, { value:"1", display:"Muhammed" }, { value:"2", display:"Ravi" }, { value:"3", display:"Ajmal" }, { value:"4", display:"Ryan" }];
const b = [{ value:"0", display:"Jamsheer", $$hashKey:"008" }, { value:"1", display:"Muhammed", $$hashKey:"009" }, { value:"2", display:"Ravi", $$hashKey:"00A" }, { value:"3", display:"Ajmal", $$hashKey:"00B" }];

// A comparer used to determine if two entries are equal.
const isSameUser = (a, b) => a.value === b.value && a.display === b.display;

// Get items that only occur in the left array,
// using the compareFunction to determine equality.
const onlyInLeft = (left, right, compareFunction) =>
left.filter(leftValue =>
!right.some(rightValue =>
compareFunction(leftValue, rightValue)));

const onlyInA = onlyInLeft(a, b, isSameUser);
const onlyInB = onlyInLeft(b, a, isSameUser);

const result = [...onlyInA, ...onlyInB];

console.log(result);

Underscore JS difference on array and array with objects

You could do this by using the _.reject method.

For example:

_.reject(names, function(name) {
return blockedIds.indexOf(name.id) > -1;
});

See this JSFiddle.

Finding difference between two arrays that contain objects

Try following, it works for just two arrays

_.reject(one, function(obj){ return _.findWhere(two, obj); });

But objects should be like bellow

var one = [
{ _id:"53c907016b7536a18b0001ab", title:"..." },
{ _id:"53c90942b879875e2b0001ec", title:"..." }
]

var two = [
{ _id:"53c907016b7536a18b0001ab", title:"..." }
]

Compare 2 arrays of objects with Underscore to find the differnce

Take a look to this:

var a = [
{"ListingId":1762276,"Rating":3,"ListPrice":7411828,"PropertyType":"Residential"},
{"ListingId":1826692,"Rating":3,"ListPrice":650000,"PropertyType":"Residential"},
{"ListingId":1833283,"Rating":4,"ListPrice":950000,"PropertyType":"Residential"},
{"ListingId":1832134,"Rating":3,"ListPrice":850000,"PropertyType":"Residential"},
{"ListingId":1829932,"Rating":4,"ListPrice":750000,"PropertyType":"Residential"},
{"ListingId":1827548,"Rating":5,"ListPrice":650000,"PropertyType":"Residential"}
];

var b = [
{"ListingId":1762276,"Rating":2,"ListPrice":7411828,"PropertyType":"Residential"},
{"ListingId":1826692,"Rating":3,"ListPrice":650000,"PropertyType":"Residential"},
{"ListingId":1833283,"Rating":4,"ListPrice":950000,"PropertyType":"Residential"},
{"ListingId":1832134,"Rating":3,"ListPrice":850000,"PropertyType":"Residential"},
{"ListingId":1829932,"Rating":4,"ListPrice":750000,"PropertyType":"Residential"},
{"ListingId":1827548,"Rating":5,"ListPrice":650000,"PropertyType":"Residential"}
]

var difference = function(array){
var rest = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));

var containsEquals = function(obj, target) {
if (obj == null) return false;
return _.any(obj, function(value) {
return _.isEqual(value, target);
});
};

return _.filter(array, function(value){ return ! containsEquals(rest, value); });
};

console.log(JSON.stringify(difference(b, a)));
> [{"ListingId":1762276,"Rating":2,"ListPrice":7411828,"PropertyType":"Residential"}]

The code is based on the original function difference from underscore, but it performs a deep comparison between objects using isEqual.

2 arrays of object between difference

If you want to find the difference between two objects you can try using the _.filter and _.findWhere functions:

var array1 = [{a: 1},{b: 2}];
var array2 = [{a: 1}];

_.filter(array1, function(obj){ return !_.findWhere(array2, obj); });


Related Topics



Leave a reply



Submit