Я столкнулся с той же проблемой и решил написать свое собственное решение. Но так как я хочу также сравнить массивы с объектами и наоборот, я создал общее решение. Я решил добавить функции в прототип, но их легко переписать в автономные функции. Вот код:
Array.prototype.equals = Object.prototype.equals = function(b) {
var ar = JSON.parse(JSON.stringify(b));
var err = false;
for(var key in this) {
if(this.hasOwnProperty(key)) {
var found = ar.find(this[key]);
if(found > -1) {
if(Object.prototype.toString.call(ar) === "[object Object]") {
delete ar[Object.keys(ar)[found]];
}
else {
ar.splice(found, 1);
}
}
else {
err = true;
break;
}
}
};
if(Object.keys(ar).length > 0 || err) {
return false;
}
return true;
}
Array.prototype.find = Object.prototype.find = function(v) {
var f = -1;
for(var i in this) {
if(this.hasOwnProperty(i)) {
if(Object.prototype.toString.call(this[i]) === "[object Array]" || Object.prototype.toString.call(this[i]) === "[object Object]") {
if(this[i].equals(v)) {
f = (typeof(i) == "number") ? i : Object.keys(this).indexOf(i);
}
}
else if(this[i] === v) {
f = (typeof(i) == "number") ? i : Object.keys(this).indexOf(i);
}
}
}
return f;
}
Этот алгоритм разбит на две части; Сама функция equals и функция для поиска числового индекса свойства в массиве / объекте. Функция find нужна только потому, что indexof находит только числа и строки, а не объекты.
Можно назвать так:
({a: 1, b: "h"}).equals({a: 1, b: "h"});
Функция возвращает true или false, в этом случае true.
Алгоритм также позволяет сравнивать очень сложные объекты:
({a: 1, b: "hello", c: ["w", "o", "r", "l", "d", {answer1: "should be", answer2: true}]}).equals({b: "hello", a: 1, c: ["w", "d", "o", "r", {answer1: "should be", answer2: true}, "l"]})
Верхний пример вернет true, даже если свойства имеют другой порядок. Одна небольшая деталь, на которую нужно обратить внимание: этот код также проверяет наличие двух типов переменных одного и того же типа, поэтому «3» - это не то же самое, что и 3.