Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing Arrays of Objects in JavaScript

I want to compare 2 arrays of objects in JavaScript code. The objects have 8 total properties, but each object will not have a value for each, and the arrays are never going to be any larger than 8 items each, so maybe the brute force method of traversing each and then looking at the values of the 8 properties is the easiest way to do what I want to do, but before implementing, I wanted to see if anyone had a more elegant solution. Any thoughts?

like image 857
AdamB Avatar asked Aug 25 '08 22:08

AdamB


People also ask

Can we compare two arrays in JavaScript?

While JavaScript does not have an inbuilt method to directly compare two arrays, it does have inbuilt methods to compare two strings. Strings can also be compared using the equality operator. Therefore, we can convert the arrays to strings, using the Array join() method, and then check if the strings are equal.

What is the best way to compare objects in JavaScript?

Comparing objects is easy, use === or Object.is(). This function returns true if they have the same reference and false if they do not. Again, let me stress, it is comparing the references to the objects, not the keys and values of the objects. So, from Example 3, Object.is(obj1,obj2); would return false.


2 Answers

As serialization doesn't work generally (only when the order of properties matches: JSON.stringify({a:1,b:2}) !== JSON.stringify({b:2,a:1})) you have to check the count of properties and compare each property as well:

const objectsEqual = (o1, o2) =>      Object.keys(o1).length === Object.keys(o2).length           && Object.keys(o1).every(p => o1[p] === o2[p]);    const obj1 = { name: 'John', age: 33};  const obj2 = { age: 33, name: 'John' };  const obj3 = { name: 'John', age: 45 };            console.log(objectsEqual(obj1, obj2)); // true  console.log(objectsEqual(obj1, obj3)); // false

If you need a deep comparison, you can call the function recursively:

const obj1 = { name: 'John', age: 33, info: { married: true, hobbies: ['sport', 'art'] } };  const obj2 = { age: 33, name: 'John', info: { hobbies: ['sport', 'art'], married: true } };  const obj3 = { name: 'John', age: 33 };    const objectsEqual = (o1, o2) =>       typeof o1 === 'object' && Object.keys(o1).length > 0           ? Object.keys(o1).length === Object.keys(o2).length               && Object.keys(o1).every(p => objectsEqual(o1[p], o2[p]))          : o1 === o2;            console.log(objectsEqual(obj1, obj2)); // true  console.log(objectsEqual(obj1, obj3)); // false

Then it's easy to use this function to compare objects in arrays:

const arr1 = [obj1, obj1]; const arr2 = [obj1, obj2]; const arr3 = [obj1, obj3];  const arraysEqual = (a1, a2) =>     a1.length === a2.length && a1.every((o, idx) => objectsEqual(o, a2[idx]));  console.log(arraysEqual(arr1, arr2)); // true console.log(arraysEqual(arr1, arr3)); // false 
like image 53
ttulka Avatar answered Oct 05 '22 15:10

ttulka


EDIT: You cannot overload operators in current, common browser-based implementations of JavaScript interpreters.

To answer the original question, one way you could do this, and mind you, this is a bit of a hack, simply serialize the two arrays to JSON and then compare the two JSON strings. That would simply tell you if the arrays are different, obviously you could do this to each of the objects within the arrays as well to see which ones were different.

Another option is to use a library which has some nice facilities for comparing objects - I use and recommend MochiKit.


EDIT: The answer kamens gave deserves consideration as well, since a single function to compare two given objects would be much smaller than any library to do what I suggest (although my suggestion would certainly work well enough).

Here is a naïve implemenation that may do just enough for you - be aware that there are potential problems with this implementation:

function objectsAreSame(x, y) {    var objectsAreSame = true;    for(var propertyName in x) {       if(x[propertyName] !== y[propertyName]) {          objectsAreSame = false;          break;       }    }    return objectsAreSame; } 

The assumption is that both objects have the same exact list of properties.

Oh, and it is probably obvious that, for better or worse, I belong to the only-one-return-point camp. :)

like image 22
Jason Bunting Avatar answered Oct 05 '22 15:10

Jason Bunting