BEARBEITEN: Sie können Operatoren in aktuellen, gängigen browserbasierten Implementierungen von JavaScript-Interpreten nicht überladen.
Um die ursprüngliche Frage zu beantworten, können Sie dies auf eine Art und Weise tun, und wohlgemerkt, dies ist ein kleiner Hack. Serialisieren Sie einfach die beiden Arrays mit JSON und vergleichen Sie dann die beiden JSON-Zeichenfolgen. Das würde Ihnen einfach sagen, ob die Arrays unterschiedlich sind. Natürlich können Sie dies auch für jedes der Objekte in den Arrays tun, um zu sehen, welche unterschiedlich sind.
Eine andere Möglichkeit ist die Verwendung einer Bibliothek, die einige nützliche Funktionen zum Vergleichen von Objekten bietet . Ich verwende und empfehle MochiKit .
EDIT: Die Antwort, die kamens gab, verdient ebenfalls Beachtung, da eine einzelne Funktion zum Vergleichen zweier gegebener Objekte viel kleiner wäre als jede Bibliothek, um das zu tun, was ich vorschlage (obwohl mein Vorschlag sicherlich gut genug funktionieren würde).
Hier ist eine naive Implementierung, die möglicherweise gerade genug für Sie tut - beachten Sie, dass bei dieser Implementierung potenzielle Probleme auftreten:
function objectsAreSame(x, y) {
var objectsAreSame = true;
for(var propertyName in x) {
if(x[propertyName] !== y[propertyName]) {
objectsAreSame = false;
break;
}
}
return objectsAreSame;
}
Die Annahme ist, dass beide Objekte dieselbe exakte Liste von Eigenschaften haben.
Oh, und es ist wahrscheinlich offensichtlich, dass ich zum Guten oder Schlechten zum einzigen Lager mit einem Rückgabepunkt gehöre. :) :)
y
es eine Supermenge von sein darfx
.JSON.stringify
, dass zwei Nicht-Objekt-Arrays (z. B. Number, String) sowie zwei Object-Arrays verglichen werden sollen, nicht jedoch zwei Objekte? Wenn ja warum? insb. beim Vergleich zweier Objekt-Arrays?{a: 1, b: 1}
und{b: 1, a: 1}
. Die Reihenfolge der Objekte ist uns egal, aber diese Zeichenfolgen unterscheiden sich deutlich.Da die Serialisierung im Allgemeinen nicht funktioniert (nur wenn die Reihenfolge der Eigenschaften übereinstimmt
JSON.stringify({a:1,b:2}) !== JSON.stringify({b:2,a:1})
:), müssen Sie die Anzahl der Eigenschaften überprüfen und auch jede Eigenschaft vergleichen: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
Wenn Sie einen umfassenden Vergleich benötigen, können Sie die Funktion rekursiv aufrufen:
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
Dann ist es einfach, diese Funktion zu verwenden, um Objekte in Arrays zu vergleichen:
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
quelle
o1 === o2
. Cool.Ich weiß, dass dies eine alte Frage ist und die Antworten gut funktionieren ... aber dies ist etwas kürzer und erfordert keine zusätzlichen Bibliotheken (dh JSON):
function arraysAreEqual(ary1,ary2){ return (ary1.join('') == ary2.join('')); }
quelle
a=["1,2"] , b=["1", "2"]
dann führt einjoin()
auf den zwei verschiedenen Arrays zu'1,2'
a=["12"], b=["1", "2"]
führt zu"12"=="12"
und ich glaube nicht, dass ein Trennzeichen Sie retten kann, weil es im Objekt selbst sein könnte. Eine Längenprüfung kann dies auch nicht beheben, daa=["12", "3"], b=["1", "23"]
return ary1.join(',') === ary2.join(',');
Ehrlich gesagt, mit maximal 8 Objekten und maximal 8 Eigenschaften pro Objekt ist es am besten, einfach jedes Objekt zu durchlaufen und die Vergleiche direkt durchzuführen. Es wird schnell und einfach sein.
Wenn Sie diese Art von Vergleichen häufig verwenden, stimme ich Jason in Bezug auf die JSON-Serialisierung zu. Andernfalls müssen Sie Ihre App nicht mit einer neuen Bibliothek oder einem neuen JSON-Serialisierungscode verlangsamen.
quelle
Ich habe ein wenig an einem einfachen Algorithmus gearbeitet, um den Inhalt zweier Objekte zu vergleichen und eine verständliche Liste von Unterschieden zurückzugeben. Ich dachte, ich würde teilen. Es leiht sich einige Ideen für jQuery aus, nämlich die
map
Funktionsimplementierung und die Überprüfung des Objekt- und Array-Typs.Es wird eine Liste von "diff-Objekten" zurückgegeben, bei denen es sich um Arrays mit den diff-Informationen handelt. Es ist sehr einfach.
Hier ist es:
// compare contents of two objects and return a list of differences // returns an array where each element is also an array in the form: // [accessor, diffType, leftValue, rightValue ] // // diffType is one of the following: // value: when primitive values at that index are different // undefined: when values in that index exist in one object but don't in // another; one of the values is always undefined // null: when a value in that index is null or undefined; values are // expressed as boolean values, indicated wheter they were nulls // type: when values in that index are of different types; values are // expressed as types // length: when arrays in that index are of different length; values are // the lengths of the arrays // function DiffObjects(o1, o2) { // choose a map() impl. // you may use $.map from jQuery if you wish var map = Array.prototype.map? function(a) { return Array.prototype.map.apply(a, Array.prototype.slice.call(arguments, 1)); } : function(a, f) { var ret = new Array(a.length), value; for ( var i = 0, length = a.length; i < length; i++ ) ret[i] = f(a[i], i); return ret.concat(); }; // shorthand for push impl. var push = Array.prototype.push; // check for null/undefined values if ((o1 == null) || (o2 == null)) { if (o1 != o2) return [["", "null", o1!=null, o2!=null]]; return undefined; // both null } // compare types if ((o1.constructor != o2.constructor) || (typeof o1 != typeof o2)) { return [["", "type", Object.prototype.toString.call(o1), Object.prototype.toString.call(o2) ]]; // different type } // compare arrays if (Object.prototype.toString.call(o1) == "[object Array]") { if (o1.length != o2.length) { return [["", "length", o1.length, o2.length]]; // different length } var diff =[]; for (var i=0; i<o1.length; i++) { // per element nested diff var innerDiff = DiffObjects(o1[i], o2[i]); if (innerDiff) { // o1[i] != o2[i] // merge diff array into parent's while including parent object name ([i]) push.apply(diff, map(innerDiff, function(o, j) { o[0]="[" + i + "]" + o[0]; return o; })); } } // if any differences were found, return them if (diff.length) return diff; // return nothing if arrays equal return undefined; } // compare object trees if (Object.prototype.toString.call(o1) == "[object Object]") { var diff =[]; // check all props in o1 for (var prop in o1) { // the double check in o1 is because in V8 objects remember keys set to undefined if ((typeof o2[prop] == "undefined") && (typeof o1[prop] != "undefined")) { // prop exists in o1 but not in o2 diff.push(["[" + prop + "]", "undefined", o1[prop], undefined]); // prop exists in o1 but not in o2 } else { // per element nested diff var innerDiff = DiffObjects(o1[prop], o2[prop]); if (innerDiff) { // o1[prop] != o2[prop] // merge diff array into parent's while including parent object name ([prop]) push.apply(diff, map(innerDiff, function(o, j) { o[0]="[" + prop + "]" + o[0]; return o; })); } } } for (var prop in o2) { // the double check in o2 is because in V8 objects remember keys set to undefined if ((typeof o1[prop] == "undefined") && (typeof o2[prop] != "undefined")) { // prop exists in o2 but not in o1 diff.push(["[" + prop + "]", "undefined", undefined, o2[prop]]); // prop exists in o2 but not in o1 } } // if any differences were found, return them if (diff.length) return diff; // return nothing if objects equal return undefined; } // if same type and not null or objects or arrays // perform primitive value comparison if (o1 != o2) return [["", "value", o1, o2]]; // return nothing if values are equal return undefined; }
quelle
Ich habe versucht
JSON.stringify()
und für mich gearbeitet.let array1 = [1,2,{value:'alpha'}] , array2 = [{value:'alpha'},'music',3,4]; JSON.stringify(array1) // "[1,2,{"value":"alpha"}]" JSON.stringify(array2) // "[{"value":"alpha"},"music",3,4]" JSON.stringify(array1) === JSON.stringify(array2); // false
quelle
Probieren Sie mal das hier an:
function used_to_compare_two_arrays(a, b) { // This block will make the array of indexed that array b contains a elements var c = a.filter(function(value, index, obj) { return b.indexOf(value) > -1; }); // This is used for making comparison that both have same length if no condition go wrong if (c.length !== a.length) { return 0; } else{ return 1; } }
quelle
return c.length === a.length;
Hier ist mein Versuch, das Assert-Modul + Node- Paket- Objekt-Hash von Node zu verwenden .
Ich nehme an, Sie möchten überprüfen, ob zwei Arrays dieselben Objekte enthalten, auch wenn diese Objekte zwischen den beiden Arrays unterschiedlich angeordnet sind.
var assert = require('assert'); var hash = require('object-hash'); var obj1 = {a: 1, b: 2, c: 333}, obj2 = {b: 2, a: 1, c: 444}, obj3 = {b: "AAA", c: 555}, obj4 = {c: 555, b: "AAA"}; var array1 = [obj1, obj2, obj3, obj4]; var array2 = [obj3, obj2, obj4, obj1]; // [obj3, obj3, obj2, obj1] should work as well // calling assert.deepEquals(array1, array2) at this point FAILS (throws an AssertionError) // even if array1 and array2 contain the same objects in different order, // because array1[0].c !== array2[0].c // sort objects in arrays by their hashes, so that if the arrays are identical, // their objects can be compared in the same order, one by one var array1 = sortArrayOnHash(array1); var array2 = sortArrayOnHash(array2); // then, this should output "PASS" try { assert.deepEqual(array1, array2); console.log("PASS"); } catch (e) { console.log("FAIL"); console.log(e); } // You could define as well something like Array.prototype.sortOnHash()... function sortArrayOnHash(array) { return array.sort(function(a, b) { return hash(a) > hash(b); }); }
quelle
Die
objectsAreSame
in der Antwort von @ JasonBunting erwähnte Funktion funktioniert für mich einwandfrei. Es gibt jedoch ein kleines Problem: Wennx[propertyName]
undy[propertyName]
Objekte (typeof x[propertyName] == 'object'
) sind, müssen Sie die Funktion rekursiv aufrufen, um sie zu vergleichen.quelle
Verwendung
_.some
von lodash: https://lodash.com/docs/4.17.11#someconst array1AndArray2NotEqual = _.some(array1, (a1, idx) => a1.key1 !== array2[idx].key1 || a1.key2 !== array2[idx].key2 || a1.key3 !== array2[idx].key3);
quelle