Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array of object deep comparison with lodash

Tags:

I've 2 array of objects that I'd deeply compare with lodash

However, I've a prob with it:

> var x = [{a:1, b:2}, {c:3, d:4}]; > var y = [{b:2, a:1}, {d:4, c:3}]; > _.difference(x,y, _.isEqual); [ { a: 1, b: 2 }, { c: 3, d: 4 } ] 

How should I compare to see that both are equal?

like image 846
Archer Avatar asked May 06 '16 06:05

Archer


People also ask

How do you check if two arrays of objects are equal in Lodash?

isEqual() Method. The Lodash _. isEqual() Method performs a deep comparison between two values to determine if they are equivalent. This method supports comparing arrays, array buffers, boolean, date objects, maps, numbers, objects, regex, sets, strings, symbols, and typed arrays.

How do you compare objects in Lodash?

In Lodash, we can deeply compare two objects using the _. isEqual() method. This method will compare both values to determine if they are equivalent.

Is Lodash efficient?

Lodash is extremely well-optimized as far as modern JS goes, but, as you may know, nothing can be faster than native implementation. Even if Lodash uses the same API under-the-hood, function call overhead is still present. Some might say that these are just some micro-optimizations.

Does Lodash isEqual care about order?

isEqual does not respect the order of Arrays contained within Sets · Issue #3640 · lodash/lodash · GitHub.


Video Answer


2 Answers

You can make use of differenceWith() with an isEqual() comparator, and invoke isEmpty to check if they are equal or not.

var isArrayEqual = function(x, y) {    return _(x).differenceWith(y, _.isEqual).isEmpty();  };    var result1 = isArrayEqual(    [{a:1, b:2}, {c:3, d:4}],    [{b:2, a:1}, {d:4, c:3}]  );    var result2 = isArrayEqual(    [{a:1, b:2, c: 1}, {c:3, d:4}],    [{b:2, a:1}, {d:4, c:3}]  );    document.write([    '<div><label>result1: ', result1, '</label></div>',    '<div><label>result2: ', result2, '</label></div>',  ].join(''));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.11.2/lodash.js"></script>

UPDATE June 22, 2018

This update is in response to the comment below:

@ryeballar if any of the array is undefined it returns true. How would you solve this. Thanks in advance buddy

As stated in the differenceWith documentation:

The order and references of result values are determined by the first array.

This means that as long as all the items in the first array will match everything else in the second array, then the resulting array from the differenceWith invocation will be empty.

An alternative solution that truly solves the problem is to use xorWith() with the same chain of functions from the solution above.

var isArrayEqual = function(x, y) {    return _(x).xorWith(y, _.isEqual).isEmpty();  };    var result1 = isArrayEqual(    [{a:1, b:2}, {c:3, d:4}],    [{b:2, a:1}, {d:4, c:3}]  );    var result2 = isArrayEqual(    [{a:1, b:2, c: 1}, {c:3, d:4}],    [{b:2, a:1}, {d:4, c:3}]  );    var result3 = isArrayEqual(    [{a:1, b:2, c: 1}, {c:3, d:4}],    [{b:2, a:1}, {d:4, c:3}, undefined]  );    console.log('result1:', result1);  console.log('result2:', result2);  console.log('result3:', result3);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
like image 139
ryeballar Avatar answered Sep 19 '22 15:09

ryeballar


Following @ryeballar answer, if you only want to import specific lodash methods you can use this notation:

import { isEmpty, isEqual, xorWith } from 'lodash';   export const isArrayEqual = (x, y) => isEmpty(xorWith(x, y, isEqual));  
like image 23
Anita Avatar answered Sep 17 '22 15:09

Anita