Array of deep comparison object with lodash

I have 2 arrays of objects that I would compare with lodash

However, I have a problem with this:

 > 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 can I compare so that both are equal?

+12
source share
3 answers

You can use the differenceWith () with the isEqual () comparator and call 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 array is not defined, it returns true. How would you solve this? Thanks in advance buddy

As stated in the differenceWith documentation:

The order and references to the values ​​of the results are determined by the first array.

This means that as long as all the elements in the first array coincide with everything else in the second array, the resulting array from the differenceWith call will be empty.

An alternative solution that really solves the problem is to use xorWith() with the same function chain as in 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> 
+28
source

I prefer pure JS since I don’t have the patience to learn underscore or lodash. Therefore, I invent what I have long dreamed of. Object.prototype.compare() . V0.0.2 makes only a small comparison, although adequate for this question.

 Object.prototype.compare = function(o){ var ok = Object.keys(this); return typeof o === "object" && ok.length === Object.keys(o).length ? ok.every(k => this[k] === o[k]) : false; }; var obj1 = {a:1,b:2,c:3}, obj2 = {c:3,a:1,b:2}, obj3 = {b:2,c:3,a:7}; document.write ("<pre>" + obj1.compare(obj2) + "</pre>\n"); document.write ("<pre>" + obj2.compare(obj3) + "</pre>\n"); document.write ("<pre>" + new Object({a:1, b:2, c:3}).compare({c:3,b:2,a:1,d:0}) + "</pre>\n"); 

Cool ... So, let's continue with the question ... I think ... since we already have Object.prototype.compare() , there should be no harm in the invention of Array.prototype.compare() . This time he will become more intelligent. It must indicate primitives from objects. One more thing: arrays are ordered; therefore, in my book [1,2] not equal to [2,1] . In addition, it simplifies the work.

 Object.prototype.compare = function(o){ var ok = Object.keys(this); return typeof o === "object" && ok.length === Object.keys(o).length ? ok.every(k => this[k] === o[k]) : false; }; Array.prototype.compare = function(a){ return this.every((e,i) => typeof a[i] === "object" ? a[i].compare(e) : a[i] === e); } var x = [{a:1, b:2}, {c:3, d:4}], y = [{b:2, a:1}, {d:4, c:3}], a = [1,2,3,4,5], b = [1,2,3,4,5], p = "fourtytwo", r = "thirtyseven", n = 42, m = 37; document.writeln(x.compare(y)); // the question is answered here document.writeln(a.compare(b)); document.writeln(p.compare(r)); // these primitives end up at Object prototype document.writeln(n.compare(m)); // so modify Object.prototype.compare () accordingly 
+2
source

After @ryeballar's answer, if you want to import only certain lodash methods, you can use this entry:

 import { isEmpty, isEqual, xorWith } from 'lodash'; export const isArrayEqual = (x, y) => isEmpty(xorWith(x, y, isEqual)); 
0
source

All Articles