Ich habe 2 verschachtelte Objekte, die unterschiedlich sind, und ich muss wissen, ob sie sich in einer ihrer verschachtelten Eigenschaften unterscheiden.
var a = {};
var b = {};
a.prop1 = 2;
a.prop2 = { prop3: 2 };
b.prop1 = 2;
b.prop2 = { prop3: 3 };
Das Objekt könnte mit verschachtelten Eigenschaften viel komplexer sein. Aber dieser ist ein gutes Beispiel. Ich habe die Möglichkeit, rekursive Funktionen oder etwas mit lodash zu verwenden ...
javascript
lodash
JLavoie
quelle
quelle
_.isEqual(value, other)
Führt einen umfassenden Vergleich zwischen zwei Werten durch, um festzustellen, ob sie gleichwertig sind. lodash.com/docs#isEqualAntworten:
Eine einfache und elegante Lösung ist die Verwendung
_.isEqual
, die einen tiefen Vergleich durchführt:Diese Lösung zeigt jedoch nicht, welche Eigenschaft unterschiedlich ist.
http://jsfiddle.net/bdkeyn0h/
quelle
_.isEqual
das ziemlich schwierig sein kann. Wenn Sie das Objekt kopieren und dort einige Werte ändern, wird weiterhin true angezeigt, da die Referenz dieselbe ist. Daher sollte man bei der Verwendung dieser Funktion vorsichtig sein.Wenn Sie wissen möchten, welche Eigenschaften unterschiedlich sind, verwenden Sie redu () :
quelle
_.reduce(a, (result, value, key) => _.isEqual(value, b[key]) ? result : result.concat(key), [])
für eine einzeilige ES6-Lösunglet edited = _.reduce(a, function(result, value, key) { return _.isEqual(value, b[key]) ? result : result.concat( { [key]: value } ); }, []);
Für alle, die über diesen Thread stolpern, ist hier eine vollständigere Lösung. Es werden zwei Objekte verglichen und Sie erhalten den Schlüssel aller Eigenschaften, die entweder nur in Objekt1 , nur in Objekt2 oder beide in Objekt1 und Objekt2 enthalten sind, aber unterschiedliche Werte haben :
Hier ist eine Beispielausgabe:
Wenn Sie sich nicht für verschachtelte Objekte interessieren und lodash überspringen möchten, können Sie das
_.isEqual
durch einen Normalwertvergleich ersetzen , zobj1[key] === obj2[key]
.quelle
Basierend auf der Antwort von Adam Boduch habe ich diese Funktion geschrieben, die zwei Objekte im tiefsten Sinne vergleicht und Pfade mit unterschiedlichen Werten sowie Pfade zurückgibt , die auf dem einen oder anderen Objekt fehlen.
Der Code wurde nicht mit Blick auf Effizienz geschrieben, und Verbesserungen in dieser Hinsicht sind sehr willkommen, aber hier ist die Grundform:
Sie können den Code mit diesem Snippet ausprobieren (es wird empfohlen, ihn im Ganzseitenmodus auszuführen):
Code-Snippet anzeigen
quelle
b
mitb.hasOwnProperty(key)
oderkey in b
nicht mit überprüfenb[key] != undefined
. Mit der alten Version, die verwendet wurdeb[key] != undefined
, hat die Funktion ein falsches Diff für Objekte zurückgegebenundefined
, die wie in enthaltencompare({disabled: undefined}, {disabled: undefined})
. In der Tat hatte die alte Version auch Probleme mitnull
; Sie können solche Probleme vermeiden, indem Sie immer===
und!==
anstelle von==
und verwenden!=
.Hier ist eine kurze Lösung:
quelle
[]
.Um rekursiv zu zeigen, wie sich ein Objekt von anderen unterscheidet, können Sie _.reduce in Kombination mit _.isEqual und _.isPlainObject verwenden . In diesem Fall können Sie vergleichen, wie sich a von b unterscheidet oder wie sich b von a unterscheidet:
quelle
Einfache Verwendungsmethode
_.isEqual
, es funktioniert für alle Vergleiche ...Also, wenn Sie unten haben:
Wenn Sie das tun:
_.isEqual(firstName, otherName);
,es wird wahr zurückgeben
Und wenn
const fullName = {firstName: "Alireza", familyName: "Dezfoolian"};
Wenn Sie das tun:
_.isEqual(firstName, fullName);
,wird false zurückgeben
quelle
Dieser Code gibt ein Objekt mit allen Eigenschaften zurück, die einen anderen Wert haben, sowie Werte beider Objekte. Nützlich, um den Unterschied zu protokollieren.
quelle
Ohne Verwendung von lodash / Unterstrich habe ich diesen Code geschrieben und arbeite gut für mich für einen tiefen Vergleich von Objekt1 mit Objekt2
quelle
Tiefenvergleich mit einer Vorlage von (verschachtelten) Eigenschaften zur Überprüfung
Dies funktioniert in der Konsole. Bei Bedarf kann Array-Unterstützung hinzugefügt werden
quelle
Ich habe einen Adam Boduch-Code gestochen, um ein tiefes Diff auszugeben - dies ist völlig ungetestet, aber die Teile sind da:
quelle
diff({}, { foo: 'lol', bar: { baz: true }}) // returns []
Wie es gefragt wurde, ist hier eine rekursive Objektvergleichsfunktion. Und ein bisschen mehr. Unter der Annahme, dass die primäre Verwendung einer solchen Funktion die Objektinspektion ist, habe ich etwas zu sagen. Ein vollständiger tiefer Vergleich ist eine schlechte Idee, wenn einige Unterschiede irrelevant sind. Zum Beispiel macht ein blinder tiefer Vergleich in TDD-Behauptungen Tests unnötig spröde. Aus diesem Grund möchte ich einen viel wertvolleren Teilunterschied einführen . Es ist ein rekursives Analogon eines früheren Beitrags zu diesem Thread. Schlüssel, die in a nicht vorhanden sind, werden ignoriert
Mit BDiff können Sie nach erwarteten Werten suchen und andere Eigenschaften tolerieren. Genau das möchten Sie für die automatische Überprüfung. Dies ermöglicht das Erstellen aller Arten von erweiterten Behauptungen. Zum Beispiel:
Zurück zur vollständigen Lösung. Das Erstellen eines vollständigen traditionellen Diff mit bdiff ist trivial:
Wenn Sie die obige Funktion für zwei komplexe Objekte ausführen, wird Folgendes ausgegeben:
Um einen Einblick in die Unterschiede zwischen den Werten zu erhalten, möchten wir möglicherweise die Diff-Ausgabe direkt auswerten () . Dafür benötigen wir eine hässlichere Version von bdiff , die syntaktisch korrekte Pfade ausgibt:
Das wird etwas Ähnliches ausgeben:
MIT-Lizenz;)
quelle
Um die Antwort von Adam Boduch zu vervollständigen, werden Unterschiede in den Eigenschaften berücksichtigt
quelle
Wenn Sie nur einen Schlüsselvergleich benötigen:
quelle
Hier ist ein einfaches Typoskript mit Lodash Deep Difference Checker, das ein neues Objekt mit nur den Unterschieden zwischen einem alten und einem neuen Objekt erzeugt.
Zum Beispiel, wenn wir hätten:
Das resultierende Objekt wäre:
Es ist auch mit mehrstufigen tiefen Objekten kompatibel. Für Arrays müssen möglicherweise einige Anpassungen vorgenommen werden.
quelle
quelle
===
direkt mit vergleichen , es{ a: 20 } === { a: 20 }
wird false zurückgegeben, da der Prototyp verglichen wird. Der richtige Weg, um Objekte in erster Linie zu vergleichen, besteht darin, sie inJSON.stringify()
_.isEqual(f, s)
? :)f
es sich um ein Objekt handelt und Sie es erreichen,if (_.isObject(f))
gehen Sie einfach durch die Funktion zurück und treffen Sie diesen Punkt erneut. Gleiches gilt fürf (Array.isArray(f)&&Array.isArray(s))
Dies basierte auf @JLavoie unter Verwendung von lodash
https://jsfiddle.net/EmilianoBarboza/0g0sn3b9/8/
quelle
nur mit Vanille js
quelle
Um auf der Antwort von Sridhar Gudimela aufzubauen , wird sie hier so aktualisiert, dass Flow glücklich wird:
quelle