Reputation: 559
I am trying to compare two array of objects. Below is my code.
var result = identical([
{"depid": "100", "depname": ""},
{"city": "abc", "state": "xyz"},
{"firstName": "John", "lastName": "Doe", "contactno": {"ph": 12345, "mob": 485428428}}
], [
{"firstName": "John", "lastName": "Doe", "contactno": {"ph": 12345, "mob": 485428428}},
{"depid": "100", "depname": ""},
{"city": "abc", "state": "xyz"}
]);
console.log(result); // returns false
function identical(a, b) {
function sort(object) {
if (typeof object !== "object" || object === null) {
return object;
}
return Object.keys(object).sort().map(function (key) {
return {
key: key,
value: sort(object[key])
};
});
}
return JSON.stringify(sort(a)) === JSON.stringify(sort(b));
};
I want to know why I am getting result as false while comparing the above two array of objects.
If I pass the below object, the result is true
var result = identical([
{"firstName": "John", "lastName": "Doe", "contactno": {"ph": 12345, "mob": 485428428}},
{"depid": "100", "depname": ""},
{"city": "abc", "state": "xyz"}
], [
{"firstName": "John", "lastName": "Doe", "contactno": {"ph": 12345, "mob": 485428428}},
{"depid": "100", "depname": ""},
{"city": "abc", "state": "xyz"}
]);
How to compare based on keys alone and without seeing the order of objects ?
Upvotes: 1
Views: 366
Reputation: 4798
One of the solutions I found, is to define a function to test the equality of the objects, and then you need to call that function for each element on the array. this code works fine for me:
Object.prototype.equals = function(x) {
for(p in this) {
switch(typeof(this[p])) {
case 'object':
if (!this[p].equals(x[p])) { return false }; break;
case 'function':
if (typeof(x[p])=='undefined' || (p != 'equals' && this[p].toString() != x[p].toString())) { return false; }; break;
default:
if (this[p] != x[p]) { return false; }
}
}
for(p in x) {
if(typeof(this[p])=='undefined') {return false;}
}
return true;
}
Source : Object comparison in JavaScript
function identical (arr1, arr2) {
if(arr1.length != arr2.length) {
return false;
}
var exists = arr1.length;
for(var i = 0; i<arr1.length; i++) {
for(var j =0; j<arr2.length ; j++) {
if(Object.keys(arr1[i]).equals(Object.keys(arr2[j]))) {
exists--;
}
}
}
return !exists;
}
Now the result of this code is true
var result = identical([
{"firstName": "John", "lastName": "Doe", "contactno": {"ph": 12345, "mob": 485428428}},
{"depid": "100", "depname": ""},
{"city": "abc", "state": "xyz"}
], [
{"firstName": "John", "lastName": "Doe", "contactno": {"ph": 12345, "mob": 485428428}},
{"depid": "100", "depname": ""},
{"city": "abc", "state": "xyz"}
]);
Edit :
To compare only keys, you need to use :
Object.keys(arr1[i]).equals(Object.keys(arr2[j])
instead of
arr1[i].equals(arr2[j])
I made the update on the code above.
Upvotes: 3
Reputation: 358
It fails because a is an array, so sort(a) sorts a with respect to the array indexes. You can try:
var l = ['a','b'];
alert(Object.keys(l));
it shows:
0,1
So sort(a) sorts don't put the objects inside in a meaningful order. It does not even care about what is in the array.
It you want to compare arrays of objects, I would suggest to use your function sort on each object of the array, then jsonify each object in the array, then sort the array of strings and compare the two resulting sorted arrays of strings.
Upvotes: 1
Reputation: 2568
While serializing objects to string the keys aren't guaranteed to be in same order. To compare irrespective of order check this Comparing two json arrays
Upvotes: 1