Ich möchte zwei Arrays miteinander vergleichen ... idealerweise effizient. Nichts Besonderes, nur true
, wenn sie identisch sind, und false
, falls nicht. Es überrascht nicht, dass der Vergleichsoperator nicht funktioniert.
var a1 = [1,2,3];
var a2 = [1,2,3];
console.log(a1==a2); // Returns false
console.log(JSON.stringify(a1)==JSON.stringify(a2)); // Returns true
JSON-Codierung für jedes Array ist ein Muss. Aber gibt es eine schnellere oder "bessere" Möglichkeit, Arrays einfach zu vergleichen, ohne jeden Wert durchlaufen zu müssen?
Um Arrays zu vergleichen, durchlaufen Sie sie und vergleichen Sie jeden Wert:
// Warn if overriding existing method
if(Array.prototype.equals)
console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");
// attach the .equals method to Array's prototype to call it on any array
Array.prototype.equals = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0, l=this.length; i < l; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
}
// Hide method from for-in loops
Object.defineProperty(Array.prototype, "equals", {enumerable: false});
[1, 2, [3, 4]].equals([1, 2, [3, 2]]) === false;
[1, "2,3"].equals([1, 2, 3]) === false;
[1, 2, [3, 4]].equals([1, 2, [3, 4]]) === true;
[1, 2, 1, 2].equals([1, 2, 1, 2]) === true;
Sie können sagen "Aber es ist viel schneller, Strings zu vergleichen - keine Schleifen ..." Erste rekursive Schleife, die Array in String konvertiert, und zweite, die zwei Strings vergleicht. Diese Methode ist also schneller als die Verwendung von Zeichenfolge.
Ich glaube, dass größere Datenmengen immer in Arrays gespeichert werden sollten, nicht in Objekten. Wenn Sie jedoch Objekte verwenden, können diese auch teilweise verglichen werden.
Hier ist wie:
Ich habe oben gesagt, dass zwei Objekte instance niemals gleich sein werden, selbst wenn sie im Moment die gleichen Daten enthalten:
({a:1, foo:"bar", numberOfTheBeast: 666}) == ({a:1, foo:"bar", numberOfTheBeast: 666}) //false
Dies hat einen Grund, da es zum Beispiel private Variablen in Objekten geben kann.
Wenn Sie jedoch nur die Objektstruktur verwenden, um Daten zu enthalten, ist der Vergleich noch möglich:
Object.prototype.equals = function(object2) {
//For the first loop, we only check for types
for (propName in this) {
//Check for inherited methods and properties - like .equals itself
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
//Return false if the return value is different
if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
return false;
}
//Check instance type
else if (typeof this[propName] != typeof object2[propName]) {
//Different types => not equal
return false;
}
}
//Now a deeper check using other objects property names
for(propName in object2) {
//We must check instances anyway, there may be a property that only exists in object2
//I wonder, if remembering the checked values from the first loop would be faster or not
if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
return false;
}
else if (typeof this[propName] != typeof object2[propName]) {
return false;
}
//If the property is inherited, do not check any more (it must be equa if both objects inherit it)
if(!this.hasOwnProperty(propName))
continue;
//Now the detail check and recursion
//This returns the script back to the array comparing
/**REQUIRES Array.equals**/
if (this[propName] instanceof Array && object2[propName] instanceof Array) {
// recurse into the nested arrays
if (!this[propName].equals(object2[propName]))
return false;
}
else if (this[propName] instanceof Object && object2[propName] instanceof Object) {
// recurse into another objects
//console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\"");
if (!this[propName].equals(object2[propName]))
return false;
}
//Normal value comparison for strings and numbers
else if(this[propName] != object2[propName]) {
return false;
}
}
//If everything passed, let's say YES
return true;
}
Denken Sie jedoch daran, dass dies zum Vergleich von JSON-ähnlichen Daten und nicht von Klasseninstanzen und anderen Dingen dienen soll. Wenn Sie mehr komplizierte Objekte vergleichen möchten, sehen Sie diese Antwort und ihre überlange Funktion .
.__ Damit dies mit Array.equals
funktioniert, müssen Sie die ursprüngliche Funktion ein wenig bearbeiten:
...
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
/**REQUIRES OBJECT COMPARE**/
else if (this[i] instanceof Object && array[i] instanceof Object) {
// recurse into another objects
//console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\"");
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
...
Ich habe ein kleines Testwerkzeug für beide Funktionen erstellt.
indexOf
und contains
Samy Bencherif hat nützliche Funktionen für den Fall vorbereitet, dass Sie in verschachtelten Arrays nach einem bestimmten Objekt suchen, das hier verfügbar ist: https://jsfiddle.net/SamyBencherif/8352y6yw/
Dies funktioniert zwar nur für skalare Arrays (siehe Hinweis unten), ist jedoch kurz:
array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]})
Rr, in ECMAScript 6/CoffeeScript/TypeScript mit Pfeilfunktionen:
array1.length === array2.length && array1.every((value, index) => value === array2[index])
(Hinweis: "Skalar" bedeutet hier Werte, die direkt mit ===
verglichen werden können. Also: Zahlen, Strings, Objekte nach Referenz, Funktionen nach Referenz. Weitere Informationen zu den Vergleichsoperatoren finden Sie unter die MDN-Referenz .
UPDATE
Nach dem, was ich aus den Kommentaren gelesen habe, kann das Sortieren des Arrays und das Vergleichen zu einem genauen Ergebnis führen:
array1.length === array2.length && array1.sort().every(function(value, index) { return value === array2.sort()[index]});
Z.B:
array1 = [2,3,1,4];
array2 = [1,2,3,4];
Dann würde der obige Code true
geben
Ich benutze die Underscore-Bibliothek gerne für Array-/Objekt-schwere Codierungsprojekte ... In Underscore und Lodash, egal ob Sie Arrays oder Objekte vergleichen, es sieht einfach so aus:
_.isEqual(array1, array2) // returns a boolean
_.isEqual(object1, object2) // returns a boolean
Ich denke, dies ist der einfachste Weg, dies mit JSON stringify zu tun, und es kann in einigen Situationen die beste Lösung sein:
JSON.stringify(a1) === JSON.stringify(a2);
Dadurch werden die Objekte a1
und a2
in Strings umgewandelt, damit sie miteinander verglichen werden können. Die Reihenfolge ist in den meisten Fällen wichtig, da das Objekt mithilfe eines Sortieralgorithmus sortiert werden kann, der in einer der obigen Antworten angezeigt wird.
Bitte beachten Sie, dass Sie nicht mehr das Objekt, sondern die Zeichenfolgendarstellung des Objekts vergleichen. Es kann nicht genau das sein, was Sie wollen.
Es ist unklar, was Sie mit "identisch" meinen. Sind beispielsweise die Arrays a
und b
identisch (beachten Sie die verschachtelten Arrays)?
var a = ["foo", ["bar"]], b = ["foo", ["bar"]];
Hier ist eine optimierte Array-Vergleichsfunktion, die die entsprechenden Elemente jedes Arrays unter Verwendung strenger Gleichheit miteinander vergleicht und keinen rekursiven Vergleich von Array-Elementen vornimmt, die selbst Arrays sind. Dies bedeutet, dass im obigen Beispiel arraysIdentical(a, b)
false
zurückgeben würde. Es funktioniert im allgemeinen Fall, dass JSON- und join()
-basierte Lösungen nicht:
function arraysIdentical(a, b) {
var i = a.length;
if (i != b.length) return false;
while (i--) {
if (a[i] !== b[i]) return false;
}
return true;
};
Ich finde es falsch zu sagen, dass eine bestimmte Implementierung "The Right Way ™" ist, wenn sie im Gegensatz zu einer "falschen" Lösung nur "richtig" ("richtig") ist. Die Lösung von Tomáš ist eine deutliche Verbesserung gegenüber dem stringbasierten Array-Vergleich, aber das bedeutet nicht, dass es objektiv "richtig" ist. Was ist überhaupt richtig ? Ist es das schnellste? Ist es das flexibelste? Ist es am einfachsten zu verstehen? Ist es das schnellste Debugging? Verwendet es die wenigsten Operationen? Hat es irgendwelche Nebenwirkungen? Keine Lösung kann das Beste von allem haben.
Tomás könnte sagen, dass seine Lösung schnell ist, aber ich würde auch sagen, dass sie unnötig kompliziert ist. Es wird versucht, eine All-in-One-Lösung zu sein, die für alle geschachtelten oder nicht geschachtelten Arrays funktioniert. Tatsächlich akzeptiert es sogar mehr als nur Arrays als Eingabe und versucht dennoch, eine "gültige" Antwort zu geben.
Meine Antwort wird das Problem anders angehen. Ich beginne mit einer generischen arrayCompare
Prozedur, die sich nur mit dem Durchlaufen der Arrays befasst. Von dort aus bauen wir unsere anderen grundlegenden Vergleichsfunktionen wie arrayEqual
und arrayDeepEqual
usw
// arrayCompare :: (a -> a -> Bool) -> [a] -> [a] -> Bool
const arrayCompare = f => ([x,...xs]) => ([y,...ys]) =>
x === undefined && y === undefined
? true
: Boolean (f (x) (y)) && arrayCompare (f) (xs) (ys)
Meiner Meinung nach benötigt die beste Art von Code nicht einmal Kommentare, und dies ist keine Ausnahme. Hier passiert so wenig, dass Sie das Verhalten dieses Verfahrens fast mühelos nachvollziehen können. Sicher, ein Teil der ES6-Syntax scheint Ihnen jetzt fremd zu sein, aber das liegt nur daran, dass ES6 relativ neu ist.
Wie der Typ andeutet, übernimmt arrayCompare
die Vergleichsfunktion f
und zwei Eingabearrays xs
und ys
. Zum größten Teil rufen wir nur f (x) (y)
für jedes Element in den Eingabearrays auf. Wir geben ein frühes false
zurück, wenn das benutzerdefinierte f
false
zurückgibt - dank der Kurzschlussauswertung von &&
. Ja, dies bedeutet, dass der Komparator die Iteration vorzeitig beenden und verhindern kann, dass der Rest des Eingabearrays durchlaufen wird, wenn dies nicht erforderlich ist.
Als nächstes können wir mit unserer Funktion arrayCompare
auf einfache Weise andere Funktionen erstellen, die wir möglicherweise benötigen. Wir beginnen mit dem elementaren arrayEqual
…
// equal :: a -> a -> Bool
const equal = x => y =>
x === y // notice: triple equal
// arrayEqual :: [a] -> [a] -> Bool
const arrayEqual =
arrayCompare (equal)
const xs = [1,2,3]
const ys = [1,2,3]
console.log (arrayEqual (xs) (ys)) //=> true
// (1 === 1) && (2 === 2) && (3 === 3) //=> true
const zs = ['1','2','3']
console.log (arrayEqual (xs) (zs)) //=> false
// (1 === '1') //=> false
So einfach ist das. arrayEqual
kann mit arrayCompare
und einer Komparatorfunktion definiert werden, die a
mit b
unter Verwendung von ===
vergleicht (für strikte Gleichheit).
Beachten Sie, dass wir equal
auch als eigene Funktion definieren. Dies unterstreicht die Rolle von arrayCompare
als Funktion höherer Ordnung, um unseren Komparator erster Ordnung im Kontext eines anderen Datentyps (Array) zu verwenden.
Genauso einfach könnten wir arrayLooseEqual
mit einem ==
Definieren. Wenn Sie nun 1
(Zahl) mit '1'
(Zeichenfolge) vergleichen, lautet das Ergebnis true
…
// looseEqual :: a -> a -> Bool
const looseEqual = x => y =>
x == y // notice: double equal
// arrayLooseEqual :: [a] -> [a] -> Bool
const arrayLooseEqual =
arrayCompare (looseEqual)
const xs = [1,2,3]
const ys = ['1','2','3']
console.log (arrayLooseEqual (xs) (ys)) //=> true
// (1 == '1') && (2 == '2') && (3 == '3') //=> true
Sie haben wahrscheinlich bemerkt, dass dies nur ein flacher Vergleich ist. Sicher ist Tomás 'Lösung "The Right Way ™", weil es einen tiefen Vergleich impliziert, oder?
Nun, unser arrayCompare
-Verfahren ist vielseitig genug, um einen tiefen Gleichheitstest zum Kinderspiel zu machen ...
// isArray :: a -> Bool
const isArray =
Array.isArray
// arrayDeepCompare :: (a -> a -> Bool) -> [a] -> [a] -> Bool
const arrayDeepCompare = f =>
arrayCompare (a => b =>
isArray (a) && isArray (b)
? arrayDeepCompare (f) (a) (b)
: f (a) (b))
const xs = [1,[2,[3]]]
const ys = [1,[2,['3']]]
console.log (arrayDeepCompare (equal) (xs) (ys)) //=> false
// (1 === 1) && (2 === 2) && (3 === '3') //=> false
console.log (arrayDeepCompare (looseEqual) (xs) (ys)) //=> true
// (1 == 1) && (2 == 2) && (3 == '3') //=> true
So einfach ist das. Wir bauen einen tiefen Komparator mit einer anderen Funktion höherer Ordnung. Diesmal verpacken wir arrayCompare
mit einem benutzerdefinierten Komparator, der überprüft, ob a
und b
Arrays sind. Wenn ja, wende arrayDeepCompare
erneut an, andernfalls vergleiche a
und b
mit dem benutzerdefinierten Komparator (f
). Dies ermöglicht es uns, das tiefe Vergleichsverhalten von dem tatsächlichen Vergleich der einzelnen Elemente zu trennen. Dh, wie das obige Beispiel zeigt, können wir mit equal
, looseEqual
oder einem anderen Vergleicher, den wir erstellen, tiefgehend vergleichen.
Da arrayDeepCompare
Currys ist, können wir es teilweise anwenden, wie wir es auch in den vorherigen Beispielen getan haben
// arrayDeepEqual :: [a] -> [a] -> Bool
const arrayDeepEqual =
arrayDeepCompare (equal)
// arrayDeepLooseEqual :: [a] -> [a] -> Bool
const arrayDeepLooseEqual =
arrayDeepCompare (looseEqual)
Für mich ist dies bereits eine deutliche Verbesserung gegenüber Tomás 'Lösung, da ich je nach Bedarf explizit einen flachen oder tiefen Vergleich für meine Arrays wählen kann.
Was ist nun, wenn Sie eine Reihe von Objekten oder etwas haben? Vielleicht möchten Sie diese Arrays als "gleich" betrachten, wenn jedes Objekt den gleichen id
Wert hat ...
// idEqual :: {id: Number} -> {id: Number} -> Bool
const idEqual = x => y =>
x.id !== undefined && x.id === y.id
// arrayIdEqual :: [a] -> [a] -> Bool
const arrayIdEqual =
arrayCompare (idEqual)
const xs = [{id:1}, {id:2}]
const ys = [{id:1}, {id:2}]
console.log (arrayIdEqual (xs) (ys)) //=> true
// (1 === 1) && (2 === 2) //=> true
const zs = [{id:1}, {id:6}]
console.log (arrayIdEqual (xs) (zs)) //=> false
// (1 === 1) && (2 === 6) //=> false
So einfach ist das. Hier habe ich Vanilla JS-Objekte verwendet, aber diese Art von Komparator könnte für jeden Objekttyp funktionieren; sogar Ihre benutzerdefinierten Objekte. Die Lösung von Tomáš müsste komplett überarbeitet werden, um diese Art von Gleichstellungstest zu unterstützen
Tiefes Array mit Objekten? Kein Problem. Wir haben äußerst vielseitige generische Funktionen entwickelt, damit sie in einer Vielzahl von Anwendungsfällen eingesetzt werden können.
const xs = [{id:1}, [{id:2}]]
const ys = [{id:1}, [{id:2}]]
console.log (arrayCompare (idEqual) (xs) (ys)) //=> false
console.log (arrayDeepCompare (idEqual) (xs) (ys)) //=> true
Oder was, wenn Sie eine andere Art von völlig willkürlichem Vergleich machen wollten? Vielleicht möchte ich wissen, ob jeder x
größer ist als jeder y
…
// gt :: Number -> Number -> Bool
const gt = x => y =>
x > y
// arrayGt :: [a] -> [a] -> Bool
const arrayGt = arrayCompare (gt)
const xs = [5,10,20]
const ys = [2,4,8]
console.log (arrayGt (xs) (ys)) //=> true
// (5 > 2) && (10 > 4) && (20 > 8) //=> true
const zs = [6,12,24]
console.log (arrayGt (xs) (zs)) //=> false
// (5 > 6) //=> false
Sie können sehen, dass wir mit weniger Code tatsächlich mehr erreichen. An arrayCompare
selbst ist nichts kompliziert, und jeder der von uns erstellten benutzerdefinierten Komparatoren ist sehr einfach zu implementieren.
Mit Leichtigkeit können wir genau definieren, wie zwei Arrays verglichen werden sollen - flach, tief, streng, locker, eine Objekteigenschaft oder eine willkürliche Berechnung oder eine beliebige Kombination davon - alle unter Verwendung einer Prozedur =, arrayCompare
. Vielleicht kannst du dir sogar einen RegExp
Komparator ausdenken! Ich weiß, wie Kinder diese Regexps lieben ...
Ist es das schnellste? Nee. Aber wahrscheinlich muss es auch nicht sein. Wenn Geschwindigkeit die einzige Metrik ist, mit der die Qualität unseres Codes gemessen wird, werden viele wirklich großartige Codes weggeworfen. Deshalb nenne ich diesen Ansatz The Practical Way. Oder vielleicht um fairer zu sein, [~ # ~] ein [~ # ~] praktischer Weg. Diese Beschreibung ist für diese Antwort geeignet, da ich nicht sage, dass diese Antwort nur im Vergleich zu einer anderen Antwort praktisch ist. es ist objektiv wahr. Wir haben ein hohes Maß an Praktikabilität mit sehr wenig Code erreicht, über den man sehr leicht nachdenken kann. Kein anderer Code kann sagen, dass wir diese Beschreibung nicht verdient haben.
Ist das die "richtige" Lösung für Sie? Das liegt an Ihnen zu entscheiden. Und niemand anderes kann das für Sie tun. Nur Sie wissen, was Sie brauchen. In fast allen Fällen schätze ich einfachen, praktischen und vielseitigen Code gegenüber cleveren und schnellen. Was Sie schätzen, kann davon abweichen. Wählen Sie also, was für Sie funktioniert.
Meine alte Antwort konzentrierte sich mehr auf die Zerlegung von arrayEqual
in winzige Prozeduren. Es ist eine interessante Übung, aber nicht der beste (praktischste) Weg, um dieses Problem anzugehen. Wenn Sie interessiert sind, können Sie diesen Versionsverlauf anzeigen.
Im Geiste der ursprünglichen Frage:
Ich möchte zwei Arrays vergleichen ... idealerweise effizient. Nichts Phantasie, nur wahr, wenn sie identisch sind, und falsch, wenn nicht.
Ich habe Leistungstests für einige der hier vorgeschlagenen einfacheren Vorschläge mit den folgenden Ergebnissen (schnell bis langsam) durchgeführt:
while (67%) von Tim Down
var i = a1.length;
while (i--) {
if (a1[i] !== a2[i]) return false;
}
return true
alle (69%) vom Benutzer2782196
a1.every((v,i)=> v === a2[i]);
reduzieren Sie (74%) durch DEIs
a1.reduce((a, b) => a && a2.includes(b), true);
join & toString (78%) von Gaizka Allende & vivek
a1.join('') === a2.join('');
a1.toString() === a2.toString();
half toString (90%) von Victor Palomo
a1 == a2.toString();
stringify (100%) von radtek
JSON.stringify(a1) === JSON.stringify(a2);
Note In den folgenden Beispielen wird davon ausgegangen, dass die Arrays sortierte eindimensionale Arrays sind. Der
.length
-Vergleich wurde für einen gemeinsamen Benchmark entfernt (fügen Siea1.length === a2.length
zu einem der Vorschläge hinzu und Sie erhalten eine Leistungssteigerung von ~ 10%). Wählen Sie die Lösung, die für Sie am besten geeignet ist, und wissen Sie, wie schnell und begrenzt jede ist.Unbezogene Anmerkung: Es ist interessant zu sehen, wie die Leute den auslöserischen John Waynes über den Down-Voting-Button bei absolut legitimen Antworten auf diese Frage erhalten.
Wenn ich Tomáš Zatos Antwort aufbaue, stimme ich zu, dass das Durchlaufen der Arrays das schnellste ist. Außerdem sollte die Funktion (wie andere bereits erwähnt haben) gleich/gleich heißen, nicht vergleichen. In Anbetracht dessen habe ich die Funktion geändert, um den Vergleich von Arrays auf Ähnlichkeit zu handhaben - d. H. Sie haben die gleichen Elemente, aber außer Ordnung - für den persönlichen Gebrauch, und ich dachte, ich würde sie hierher werfen, damit jeder sie sehen kann.
Array.prototype.equals = function (array, strict) {
if (!array)
return false;
if (arguments.length == 1)
strict = true;
if (this.length != array.length)
return false;
for (var i = 0; i < this.length; i++) {
if (this[i] instanceof Array && array[i] instanceof Array) {
if (!this[i].equals(array[i], strict))
return false;
}
else if (strict && this[i] != array[i]) {
return false;
}
else if (!strict) {
return this.sort().equals(array.sort(), true);
}
}
return true;
}
Diese Funktion verwendet einen zusätzlichen Parameter von strict, der standardmäßig auf true festgelegt ist. Dieser strikte Parameter definiert, ob die Arrays sowohl in Inhalt als auch in der Reihenfolge dieser Inhalte völlig gleich sein müssen oder einfach nur den gleichen Inhalt enthalten.
Beispiel:
var arr1 = [1, 2, 3, 4];
var arr2 = [2, 1, 4, 3]; // Loosely equal to 1
var arr3 = [2, 2, 3, 4]; // Not equal to 1
var arr4 = [1, 2, 3, 4]; // Strictly equal to 1
arr1.equals(arr2); // false
arr1.equals(arr2, false); // true
arr1.equals(arr3); // false
arr1.equals(arr3, false); // false
arr1.equals(arr4); // true
arr1.equals(arr4, false); // true
Ich habe auch ein kurzes jsfiddle mit der Funktion und diesem Beispiel geschrieben:
http://jsfiddle.net/Roundaround/DLkxX/
Auch wenn dies viele Antworten hat, von denen ich glaube, dass sie hilfreich sind:
const newArray = [ ...new Set( [...arr1, ...arr2] ) ]
In der Frage wird nicht angegeben, wie die Struktur des Arrays aussehen wird. Wenn Sie also sicher sind, dass Sie keine verschachtelten Arrays oder Objekte in Ihrem Array haben (es ist mir passiert, deshalb kam ich zu dieser Antwort) der obige Code wird funktionieren.
Was passiert, ist, dass wir Spread-Operator (...) verwenden, um beide Arrays zusammenzuführen, und dann Set verwenden, um alle Duplikate zu entfernen. Sobald Sie das haben, können Sie deren Größen vergleichen. Wenn alle drei Arrays die gleiche Größe haben, können Sie loslegen.
Diese Antwort auch ignoriert die Reihenfolge der Elemente, wie gesagt, die genaue Situation ist mir passiert, so dass vielleicht jemand in derselben Situation hier landen könnte (wie ich).
Edit1.
Beantwortung der Frage von Dmitry Grinko: "Warum haben Sie den Spread-Operator (...) hier - ... neues Set verwendet? Es funktioniert nicht"
Betrachten Sie diesen Code:
const arr1 = [ 'a', 'b' ]
const arr2 = [ 'a', 'b', 'c' ]
const newArray = [ new Set( [...arr1, ...arr2] ) ]
console.log(newArray)
Du wirst kriegen
[ Set { 'a', 'b', 'c' } ]
Um mit diesem Wert arbeiten zu können, müssen Sie einige Set-Eigenschaften verwenden (siehe https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set ) .. Wenn Sie jedoch diesen Code verwenden:
const arr1 = [ 'a', 'b' ]
const arr2 = [ 'a', 'b', 'c' ]
const newArray = [ ...new Set( [...arr1, ...arr2] ) ]
console.log(newArray)
Du wirst kriegen
[ 'a', 'b', 'c' ]
Das ist der Unterschied, der erstere würde mir ein Set geben, es würde auch funktionieren, da ich die Größe dieses Sets bekommen könnte, aber das letztere gibt mir das Array, das ich brauche, was die Auflösung direkter macht.
In den gleichen Zeilen wie JSON.encode soll join () verwendet werden.
function checkArrays( arrA, arrB ){
//check if lengths are different
if(arrA.length !== arrB.length) return false;
//slice so we do not effect the original
//sort makes sure they are in order
//join makes it a string so we can do a string compare
var cA = arrA.slice().sort().join(",");
var cB = arrB.slice().sort().join(",");
return cA===cB;
}
var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"]; //will return true
console.log( checkArrays(a,b) ); //true
console.log( checkArrays(a,c) ); //false
console.log( checkArrays(a,d) ); //false
console.log( checkArrays(a,e) ); //true
Das einzige Problem ist, wenn Sie sich für Typen interessieren, die beim letzten Vergleich getestet wurden.
function checkArrays( arrA, arrB ){
//check if lengths are different
if(arrA.length !== arrB.length) return false;
//slice so we do not effect the orginal
//sort makes sure they are in order
var cA = arrA.slice().sort();
var cB = arrB.slice().sort();
for(var i=0;i<cA.length;i++){
if(cA[i]!==cB[i]) return false;
}
return true;
}
var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];
console.log( checkArrays(a,b) ); //true
console.log( checkArrays(a,c) ); //false
console.log( checkArrays(a,d) ); //false
console.log( checkArrays(a,e) ); //false
Wenn die Reihenfolge gleich bleiben soll, als nur eine Schleife, ist keine Sortierung erforderlich.
function checkArrays( arrA, arrB ){
//check if lengths are different
if(arrA.length !== arrB.length) return false;
for(var i=0;i<arrA.length;i++){
if(arrA[i]!==arrB[i]) return false;
}
return true;
}
var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];
console.log( checkArrays(a,a) ); //true
console.log( checkArrays(a,b) ); //false
console.log( checkArrays(a,c) ); //false
console.log( checkArrays(a,d) ); //false
console.log( checkArrays(a,e) ); //false
Wenn es sich nur um zwei Arrays von Zahlen oder Strings handelt, handelt es sich um ein schnelles einzeiliges Array
const array1 = [1, 2, 3];
const array2 = [1, 3, 4];
console.log(array1.join(',') === array2.join(',')) //false
const array3 = [1, 2, 3];
const array4 = [1, 2, 3];
console.log(array3.join(',') === array4.join(',')) //true
für eindimensionale Arrays können Sie einfach Folgendes verwenden:
arr1.sort().toString() == arr2.sort().toString()
dies kümmert sich auch um Arrays mit nicht übereinstimmendem Index.
Hier ist eine TypeScript-Version:
//https://stackoverflow.com/a/16436975/2589276
export function arraysEqual<T>(a: Array<T>, b: Array<T>): boolean {
if (a === b) return true
if (a == null || b == null) return false
if (a.length != b.length) return false
for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false
}
return true
}
//https://stackoverflow.com/a/16436975/2589276
export function arraysDeepEqual<T>(a: Array<T>, b: Array<T>): boolean {
return JSON.stringify(a) === JSON.stringify(b)
}
Einige Testfälle für Mokka:
it('arraysEqual', function () {
let a = [1,2]
let b = [1,2]
let c = [2,3]
let d = [2, 3]
let e = ['car','Apple','banana']
let f = ['car','Apple','banana']
let g = ['car','Apple','banan8']
expect(arraysEqual(a, b)).to.equal(true)
expect(arraysEqual(c, d)).to.equal(true)
expect(arraysEqual(a, d)).to.equal(false)
expect(arraysEqual(e, f)).to.equal(true)
expect(arraysEqual(f, g)).to.equal(false)
})
it('arraysDeepEqual', function () {
let a = [1,2]
let b = [1,2]
let c = [2,3]
let d = [2, 3]
let e = ['car','Apple','banana']
let f = ['car','Apple','banana']
let g = ['car','Apple','banan8']
let h = [[1,2],'Apple','banan8']
let i = [[1,2],'Apple','banan8']
let j = [[1,3],'Apple','banan8']
expect(arraysDeepEqual(a, b)).to.equal(true)
expect(arraysDeepEqual(c, d)).to.equal(true)
expect(arraysDeepEqual(a, d)).to.equal(false)
expect(arraysDeepEqual(e, f)).to.equal(true)
expect(arraysDeepEqual(f, g)).to.equal(false)
expect(arraysDeepEqual(h, i)).to.equal(true)
expect(arraysDeepEqual(h, j)).to.equal(false)
})
Dies vergleicht 2 unsortierte Arrays:
function areEqual(a, b) {
if ( a.length != b.length) {
return false;
}
return a.filter(function(i) {
return !b.includes(i);
}).length === 0;
}
Herers meine Lösung:
/**
* Tests two data structures for equality
* @param {object} x
* @param {object} y
* @returns {boolean}
*/
var equal = function(x, y) {
if (typeof x !== typeof y) return false;
if (x instanceof Array && y instanceof Array && x.length !== y.length) return false;
if (typeof x === 'object') {
for (var p in x) if (x.hasOwnProperty(p)) {
if (typeof x[p] === 'function' && typeof y[p] === 'function') continue;
if (x[p] instanceof Array && y[p] instanceof Array && x[p].length !== y[p].length) return false;
if (typeof x[p] !== typeof y[p]) return false;
if (typeof x[p] === 'object' && typeof y[p] === 'object') { if (!equal(x[p], y[p])) return false; } else
if (x[p] !== y[p]) return false;
}
} else return x === y;
return true;
};
Funktioniert mit jeder geschachtelten Datenstruktur und ignoriert offensichtlich die Methoden der Objekte. Denken Sie nicht einmal daran, Object.prototype mit dieser Methode zu erweitern, als ich dies einmal probiert habe, brach jQuery;)
Für die meisten Arrays ist es immer noch schneller als die meisten Serialisierungslösungen. Dies ist wahrscheinlich die schnellste Vergleichsmethode für Arrays von Objektdatensätzen.
Wir könnten dies auf funktionale Weise tun, indem wir every
verwenden ( https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/every ).
function compareArrays(array1, array2) {
if (array1.length === array2.length)
return array1.every((a, index) => a === array2[index])
else
return false
}
// test
var a1 = [1,2,3];
var a2 = [1,2,3];
var a3 = ['a', 'r', 'r', 'a', 'y', '1']
var a4 = ['a', 'r', 'r', 'a', 'y', '2']
console.log(compareArrays(a1,a2)) // true
console.log(compareArrays(a1,a3)) // false
console.log(compareArrays(a3,a4)) // false
var a1 = [1,2,3,6];
var a2 = [1,2,3,5];
function check(a, b) {
return (a.length != b.length) ? false :
a.every(function(row, index) {
return a[index] == b[index];
});
}
check(a1, a2);
////// OR ///////
var a1 = [1,2,3,6];
var a2 = [1,2,3,6];
function check(a, b) {
return (a.length != b.length) ? false :
!(a.some(function(row, index) {
return a[index] != b[index];
}));
}
check(a1, a2)
Ich glaube an einfaches JS
und an ECMAScript 2015
, was süß und einfach zu verstehen ist.
var is_arrays_compare_similar = function (array1, array2) {
let flag = true;
if (array1.length == array2.length) {
// check first array1 object is available in array2 index
array1.every( array_obj => {
if (flag) {
if (!array2.includes(array_obj)) {
flag = false;
}
}
});
// then vice versa check array2 object is available in array1 index
array2.every( array_obj => {
if (flag) {
if (!array1.includes(array_obj)) {
flag = false;
}
}
});
return flag;
} else {
return false;
}
}
hoffe es hilft jemandem.
Vergleich von 2 Arrays:
var arr1 = [1,2,3];
var arr2 = [1,2,3];
function compare(arr1,arr2)
{
if((arr1 == arr2) && (arr1.length == arr2.length))
return true;
else
return false;
}
aufrufende Funktion
var isBool = compare(arr1.sort().join(),arr2.sort().join());
Wählen Sie jeweils eine unter [a] aus, und wiederholen Sie alle durch [b]:
var a = [1,4,5,9];
var b = [1,6,7,5];
for (i = 0; i < a.length; i++) {
for (z = 0; z < a.length; z++) {
if (a[i] === b[z]) {
console.log(b[z]); // if match > console.log it
}
}
}
Der Grund ist der identische oder strikte Operator (===), der mit keiner Typumwandlung verglichen wird. Wenn also beide Werte nicht denselben Wert und denselben Typ haben, werden sie nicht als gleich betrachtet.
werfen Sie einen Blick auf diesen Link, der Sie zweifelsfrei macht auf einfache Weise zu verstehen, wie der Identitätsoperator funktioniert
dieses Skript vergleicht Object, Arrays und mehrdimensionale Arrays
function compare(a,b){
var primitive=['string','number','boolean'];
if(primitive.indexOf(typeof a)!==-1 && primitive.indexOf(typeof a)===primitive.indexOf(typeof b))return a===b;
if(typeof a!==typeof b || a.length!==b.length)return false;
for(i in a){
if(!compare(a[i],b[i]))return false;
}
return true;
}
die erste Zeile prüft, ob es sich um einen primitiven Typ handelt. Wenn ja, vergleicht er die beiden Parameter.
wenn sie Objekte sind. Es iteriert über das Objekt und überprüft jedes Element rekursiv.
Verwendungszweck:
var a=[1,2,[1,2]];
var b=[1,2,[1,2]];
var isEqual=compare(a,b); //true
Diese Funktion vergleicht zwei Arrays mit beliebiger Form und Dimesionalität:
function equals(a1, a2) {
if (!Array.isArray(a1) || !Array.isArray(a2)) {
throw new Error("Arguments to function equals(a1, a2) must be arrays.");
}
if (a1.length !== a2.length) {
return false;
}
for (var i=0; i<a1.length; i++) {
if (Array.isArray(a1[i]) && Array.isArray(a2[i])) {
if (equals(a1[i], a2[i])) {
continue;
} else {
return false;
}
} else {
if (a1[i] !== a2[i]) {
return false;
}
}
}
return true;
}
Ihr Code wird den Fall nicht angemessen behandeln, wenn beide Arrays dieselben Elemente, jedoch nicht in derselben Reihenfolge haben.
Schauen Sie sich meinen Code mit Ihrem Beispiel an, das zwei Arrays vergleicht, deren Elemente Zahlen sind. Sie können ihn für andere Elementtypen ändern oder erweitern (indem Sie .join () anstelle von .toString () verwenden).
var a1 = [1,2,3];
var a2 = [1,2,3];
const arraysAreEqual = a1.sort().toString()==a2.sort().toString();
// true if both arrays have same elements else false
console.log(arraysAreEqual);
In meinem Fall enthalten verglichene Arrays nur Zahlen und Strings. Diese Funktion zeigt Ihnen, ob Arrays die gleichen Elemente enthalten.
function are_arrs_match(arr1, arr2){
return arr1.sort().toString() === arr2.sort().toString()
}
Lass es uns testen!
arr1 = [1, 2, 3, 'nik']
arr2 = ['nik', 3, 1, 2]
arr3 = [1, 2, 5]
console.log (are_arrs_match(arr1, arr2)) //true
console.log (are_arrs_match(arr1, arr3)) //false
Erweiterung der Idee von Tomáš Zato. Tomas's Array.prototype.compare sollte eigentlich Array.prototype.compareIdentical heißen.
Es gibt weiter:
[1, 2, [3, 4]].compareIdentical ([1, 2, [3, 2]]) === false;
[1, "2,3"].compareIdentical ([1, 2, 3]) === false;
[1, 2, [3, 4]].compareIdentical ([1, 2, [3, 4]]) === true;
[1, 2, 1, 2].compareIdentical ([1, 2, 1, 2]) === true;
Aber scheitert an:
[[1, 2, [3, 2]],1, 2, [3, 2]].compareIdentical([1, 2, [3, 2],[1, 2, [3, 2]]])
Hier ist (meiner Meinung nach) bessere Version:
Array.prototype.compare = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
this.sort();
array.sort();
for (var i = 0; i < this.length; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].compare(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
}
Ein anderer Ansatz mit sehr wenig Code (Verwendung von Array verkleinern und Array enthält ):
arr1.length == arr2.length && arr1.reduce((a, b) => a && arr2.includes(b), true)
Wenn Sie auch die Gleichheit der Bestellung vergleichen wollen:
arr1.length == arr2.length && arr1.reduce((a, b, i) => a && arr2[i], true)
Die length
-Prüfung stellt sicher, dass die Menge der Elemente in einem Array nicht nur eine Teilmenge des anderen ist.
Der Reduzierer wird verwendet, um durch ein Array zu gehen und nach jedem Element in einem anderen Array zu suchen. Wenn ein Element nicht gefunden wird, gibt die Reduzierungsfunktion false
zurück.
JSON.stringify(collectionNames).includes(JSON.stringify(sourceNames)) ? array.Push(collection[i]) : null
So habe ich es gemacht.
Mit einer Option zum Vergleichen der Bestellung oder nicht:
function arraysEqual(a1, a2, compareOrder) {
if (a1.length !== a2.length) {
return false;
}
return a1.every(function(value, index) {
if (compareOrder) {
return value === a2[index];
} else {
return a2.indexOf(value) > -1;
}
});
}
Rekursiv & arbeitet aufVERSCHACHTELTENArrays:
function ArrEQ(a1,a2){
return(
//:Are both elements arrays?
Array.isArray(a1)&&Array.isArray(a2)
?
//:Yes: Test each entry for equality:
a1.every((v,i)=>(ArrEQ(v,a2[i])))
:
//:No: Simple Comparison:
(a1===a2)
);;
};;
console.log( "Works With Nested Arrays:" );
console.log( ArrEQ(
[1,2,3,[4,5,[6,"SAME/IDENTICAL"]]],
[1,2,3,[4,5,[6,"SAME/IDENTICAL"]]]
));;
console.log( ArrEQ(
[1,2,3,[4,5,[6,"DIFFERENT:APPLES" ]]],
[1,2,3,[4,5,[6,"DIFFERENT:ORANGES"]]]
));;
In a simple way uning stringify but at same time thinking in complex arrays:
**Simple arrays**:
var a = [1,2,3,4];
var b = [4,2,1,4];
JSON.stringify(a.sort()) === JSON.stringify(b.sort()) // true
**Complex arrays**:
var a = [{id:5,name:'as'},{id:2,name:'bes'}];
var b = [{id:2,name:'bes'},{id:5,name:'as'}];
JSON.stringify(a.sort(function(a,b) {return a.id - b.id})) === JSON.stringify(b.sort(function(a,b) {return a.id - b.id})) // true
**Or we can create a sort function**
function sortX(a,b) {
return a.id -b.id; //change for the necessary rules
}
JSON.stringify(a.sort(sortX)) === JSON.stringify(b.sort(sortX)) // true
Ein einfacher Ansatz:
function equals(a, b) {
if ((a && !b) || (!a && b) || (!a && !b) || (a.length !== b.length)) {
return false;
}
var isDifferent = a.some(function (element, index) {
return element !== b[index];
});
return !isDifferent;
}
Meine Lösung vergleicht Objekte, keine Arrays. Dies funktioniert auf die gleiche Weise wie Tomášs, da Arrays Objekte sind, jedoch ohne die Warnung:
Object.prototype.compare_to = function(comparable){
// Is the value being compared an object
if(comparable instanceof Object){
// Count the amount of properties in @comparable
var count_of_comparable = 0;
for(p in comparable) count_of_comparable++;
// Loop through all the properties in @this
for(property in this){
// Decrements once for every property in @this
count_of_comparable--;
// Prevents an infinite loop
if(property != "compare_to"){
// Is the property in @comparable
if(property in comparable){
// Is the property also an Object
if(this[property] instanceof Object){
// Compare the properties if yes
if(!(this[property].compare_to(comparable[property]))){
// Return false if the Object properties don't match
return false;
}
// Are the values unequal
} else if(this[property] !== comparable[property]){
// Return false if they are unequal
return false;
}
} else {
// Return false if the property is not in the object being compared
return false;
}
}
}
} else {
// Return false if the value is anything other than an object
return false;
}
// Return true if their are as many properties in the comparable object as @this
return count_of_comparable == 0;
}
Ich hoffe, das hilft Ihnen oder jemandem, der nach einer Antwort sucht.
Rekursive cmp-Funktion, die mit number/string/array/object arbeitet
<script>
var cmp = function(element, target){
if(typeof element !== typeof target)
{
return false;
}
else if(typeof element === "object" && (!target || !element))
{
return target === element;
}
else if(typeof element === "object")
{
var keys_element = Object.keys(element);
var keys_target = Object.keys(target);
if(keys_element.length !== keys_target.length)
{
return false;
}
else
{
for(var i = 0; i < keys_element.length; i++)
{
if(keys_element[i] !== keys_target[i])
return false;
if(!cmp(element[keys_element[i]], target[keys_target[i]]))
return false;
}
return true;
}
}
else
{
return element === target;
}
};
console.log(cmp({
key1: 3,
key2: "string",
key3: [4, "45", {key4: [5, "6", false, null, {v:1}]}]
}, {
key1: 3,
key2: "string",
key3: [4, "45", {key4: [5, "6", false, null, {v:1}]}]
})); // true
console.log(cmp({
key1: 3,
key2: "string",
key3: [4, "45", {key4: [5, "6", false, null, {v:1}]}]
}, {
key1: 3,
key2: "string",
key3: [4, "45", {key4: [5, "6", undefined, null, {v:1}]}]
})); // false
</script>
versuchte tief-gleich und es hat funktioniert
var eq = require('deep-equal');
eq({a: 1, b: 2, c: [3, 4]}, {c: [3, 4], a: 1, b: 2});
function compareArrays(arrayA, arrayB) {
if (arrayA.length != arrayB.length) return true;
for (i = 0; i < arrayA.length; i++)
if (arrayB.indexOf(arrayA[i]) == -1) {
return true;
}
}
for (i = 0; i < arrayB.length; i++) {
if (arrayA.indexOf(arrayB[i]) == -1) {
return true;
}
}
return false;
}
Arbeitet mitMULTIPLENArgumenten mitVERSCHACHTELTENArrays:
//:Return true if all of the arrays equal.
//:Works with nested arrays.
function AllArrEQ(...arrays){
for(var i = 0; i < (arrays.length-1); i++ ){
var a1 = arrays[i+0];
var a2 = arrays[i+1];
var res =(
//:Are both elements arrays?
Array.isArray(a1)&&Array.isArray(a2)
?
//:Yes: Compare Each Sub-Array:
//:v==a1[i]
a1.every((v,i)=>(AllArrEQ(v,a2[i])))
:
//:No: Simple Comparison:
(a1===a2)
);;
if(!res){return false;}
};;
return( true );
};;
console.log( AllArrEQ(
[1,2,3,[4,5,[6,"ALL_EQUAL" ]]],
[1,2,3,[4,5,[6,"ALL_EQUAL" ]]],
[1,2,3,[4,5,[6,"ALL_EQUAL" ]]],
[1,2,3,[4,5,[6,"ALL_EQUAL" ]]],
));;
Ich habe verwendet: um ein Array zu verbinden und eine Zeichenfolge zu erstellen, die verglichen werden soll . Bei Szenarien, die komplexer als in diesem Beispiel sind, können Sie ein anderes Trennzeichen verwenden.
var a1 = [1,2,3];
var a2 = [1,2,3];
if (a1.length !== a2.length) {
console.log('a1 and a2 are not equal')
}else if(a1.join(':') === a2.join(':')){
console.log('a1 and a2 are equal')
}else{
console.log('a1 and a2 are not equal')
}
Obwohl die erste Antwort auf diese Frage richtig und gut ist, könnte der bereitgestellte Code einige Verbesserungen erfordern.
Nachfolgend finden Sie meinen eigenen Code zum Vergleichen von Arrays und Objekten. Der Code ist kurz und einfach:
Array.prototype.equals = function(otherArray) {
if (!otherArray || this.length != otherArray.length) return false;
return this.reduce(function(equal, item, index) {
var otherItem = otherArray[index];
var itemType = typeof item, otherItemType = typeof otherItem;
if (itemType !== otherItemType) return false;
return equal && (itemType === "object" ? item.equals(otherItem) : item === otherItem);
}, true);
};
if(!Object.prototype.keys) {
Object.prototype.keys = function() {
var a = [];
for (var key in this) {
if (this.hasOwnProperty(key)) a.Push(key);
}
return a;
}
Object.defineProperty(Object.prototype, "keys", {enumerable: false});
}
Object.prototype.equals = function(otherObject) {
if (!otherObject) return false;
var object = this, objectKeys = object.keys();
if (!objectKeys.equals(otherObject.keys())) return false;
return objectKeys.reduce(function(equal, key) {
var value = object[key], otherValue = otherObject[key];
var valueType = typeof value, otherValueType = typeof otherValue;
if (valueType !== otherValueType) return false;
// this will call Array.prototype.equals for arrays and Object.prototype.equals for objects
return equal && (valueType === "object" ? value.equals(otherValue) : value === otherValue);
}, true);
}
Object.defineProperty(Object.prototype, "equals", {enumerable: false});
Dieser Code unterstützt Arrays, die in Objekten verschachtelt sind, und Objekte, die in Arrays verschachtelt sind.
Sie können eine vollständige Suite von Tests sehen und den Code selbst unter dieser Antwort testen: https://repl.it/Esfz/3
Hier ist eine CoffeeScript-Version für diejenigen, die das bevorzugen:
Array.prototype.equals = (array) ->
return false if not array # if the other array is a falsy value, return
return false if @length isnt array.length # compare lengths - can save a lot of time
for item, index in @
if item instanceof Array and array[index] instanceof Array # Check if we have nested arrays
if not item.equals(array[index]) # recurse into the nested arrays
return false
else if this[index] != array[index]
return false # Warning - two different object instances will never be equal: {x:20} != {x:20}
true
Alle Credits gehen an @ tomas-zato.
Tatsächlich geben sie in der LodashDokumentation zwei ziemlich gute Beispiele zum Vergleichen und Zurückgeben neuer Arrays für Unterschiede und Ähnlichkeiten (jeweils in den folgenden Beispielen):
import { differenceWith, intersectionWith, isEqual } from 'lodash'
differenceWith(
[{ a: 1 }, { b: 1 }],
[{ a: 1 }, { b: 1 }, { c: 1 }],
isEqual
) // []... ????the bigger array needs to go first!
differenceWith(
[{ a: 1 }, { b: 1 }, { c: 1 }],
[{ a: 1 }, { b: 1 }],
isEqual,
) // [{ c: 1 }] ????
intersectionWith(
[{ a: 1 }, { b: 1 }],
[{ a: 1 }, { b: 1 }, { c: 1 }],
isEqual,
) // [{ a: 1 }, { b: 1 }] ????this one doesn't care about which is bigger
Wenn Sie nicht immer wissen, welches Array größer sein wird, können Sie eine Hilfsfunktion dafür wie folgt schreiben:
const biggerFirst = (arr1, arr2) => {
return arr1.length > arr2.length ? [arr1, arr2] : [arr2, arr1]
}
const [big, small] = biggerFirst(
[{ a: 1 }, { b: 1 }],
[{ a: 1 }, { b: 1 }, { c: 1 }],
)
differenceWith(big, small, isEqual) // ????even though we have no idea which is bigger when they are fed to biggerFirst()
Soweit ich weiß, passen diese auch sehr gut zusammen, das ist also ziemlich gut.
Ich weiß, dass es nicht zu begrüßen ist, wenn man sich auf Bibliotheken verlässt, aber dies ist die prägnanteste und sauberste Lösung, die ich für ein wirklich häufiges Problem gefunden habe. Hoffe es hilft jemandem!
Hier ist ein sehr kurzer Weg
function arrEquals(arr1, arr2){
arr1.length == arr2.length &&
arr1.filter(elt=>arr2.includes(elt)).length == arr1.length
}
Einige großartige Antworten. Aber ich möchte andere Ideen teilen, die sich beim Vergleich von Arrays als zuverlässig erwiesen haben. Wir können zwei Arrays mit JSON.stringify () vergleichen. Es erstellt einen String aus dem Array und vergleicht so zwei erhaltene Strings aus zwei Arrays auf Gleichheit
JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:1},2]) //true
JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:2},2]) //false
JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:2},[3,4],2]) //false
JSON.stringify([1,{a:1},[3,4],2]) == JSON.stringify([1,{a:2},[3,4],2]) //false
JSON.stringify([1,{a:2},[3,4],2]) == JSON.stringify([1,{a:2},[3,4],2]) //true
JSON.stringify([1,{a:2},[3,4],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //false
JSON.stringify([1,{a:2},[3,4,[4]],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //false
JSON.stringify([1,{a:2},[3,4,[5]],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //true
Wenn das Array einfach ist und die Reihenfolge wichtig ist, können diese beiden Zeilen hilfreich sein
//Assume
var a = ['a','b', 'c']; var b = ['a','e', 'c'];
if(a.length !== b.length) return false;
return !a.reduce(
function(prev,next,idx, arr){ return prev || next != b[idx] },false
);
Reduzieren Sie Spaziergänge durch eines von array und geben Sie 'false' zurück, wenn mindestens ein Element von 'a' weder dem Element von 'b' .__ entspricht