Wie vergleicht man zwei Javascript-Sets? Ich habe versucht, ==
und ===
beide geben false zurück.
a = new Set([1,2,3]);
b = new Set([1,3,2]);
a == b; //=> false
a === b; //=> false
Diese beiden Mengen sind äquivalent, da Mengen per Definition keine Reihenfolge haben (zumindest normalerweise nicht). Ich habe mir die Dokumentation zu Set on MDN angesehen und nichts Nützliches gefunden. Weiß jemand, wie man das macht?
javascript
set
ecmascript-6
Williamcodes
quelle
quelle
===
steht für Wertgleichheit, nicht für Objektgleichheit.new Set([1,2,3]) != new Set([1,2,3])
. Dies macht Javascript Set für Sätze von Sätzen unbrauchbar, da die Obermenge doppelte Teilmengen enthält. Die einzige Problemumgehung, die Ihnen in den Sinn kommt, besteht darin, alle Teilmengen in Arrays zu konvertieren, jedes Array zu sortieren und dann jedes Array als Zeichenfolge zu codieren (z. B. JSON).Antworten:
Versuche dies:
Ein funktionalerer Ansatz wäre:
Die
all
Funktion funktioniert für alle iterierbaren Objekte (zBSet
undMap
).Wenn dies
Array.from
weiter unterstützt würde, hätten wir dieall
Funktion wie folgt implementieren können:Hoffentlich hilft das.
quelle
has
zuisPartOf
oderisIn
oderelem
has
in geändertisIn
.Sie können auch versuchen:
quelle
lodash bietet
_.isEqual()
, was tiefe Vergleiche macht. Dies ist sehr praktisch, wenn Sie keine eigenen schreiben möchten. Ab Lodash 4_.isEqual()
werden die Sets ordnungsgemäß verglichen.quelle
Die andere Antwort wird gut funktionieren; Hier ist eine andere Alternative.
Beachten Sie jedoch, dass dies nicht der Fall ist tiefe Gleichheit Vergleich zu tun. So
wird false zurückgeben. Wenn die beiden oben genannten Sätze als gleich angesehen werden sollen, müssen wir beide Sätze durchlaufen und tiefe Qualitätsvergleiche für jedes Element durchführen. Wir schreiben die Existenz einer
deepEqual
Routine vor. Dann wäre die LogikWas dies bedeutet: Suchen Sie für jedes Mitglied von s1 nach einem zutiefst gleichberechtigten Mitglied von s2. Wenn gefunden, löschen Sie es, damit es nicht wieder verwendet werden kann. Die beiden Mengen sind zutiefst gleich, wenn alle Elemente in s1 in s2 gefunden werden. und s2 erschöpft ist. Ungetestet.
Dies kann hilfreich sein: http://www.2ality.com/2015/01/es6-set-operations.html .
quelle
Keine dieser Lösungen bringt die erwartete Funktionalität in eine Datenstruktur wie einen Satz von Sätzen zurück. In seinem aktuellen Zustand ist die Javascript- Menge für diesen Zweck unbrauchbar, da die Obermenge doppelte Teilmengen enthält, die Javascript fälschlicherweise als verschieden ansieht. Die einzige Lösung, die ich mir vorstellen kann, besteht darin, jede Teilmenge in ein Array zu konvertieren , zu sortieren und dann als String zu codieren (zum Beispiel JSON).
Lösung
Grundlegende Verwendung
Ultimativer Test: Satz von Sätzen
quelle
[...set1].sort().toString() === [...set2].sort().toString()
Der Grund, warum Ihr Ansatz false zurückgibt, liegt darin, dass Sie zwei verschiedene Objekte vergleichen (auch wenn sie denselben Inhalt haben). Wenn Sie also zwei verschiedene Objekte (keine Referenzen, sondern Objekte) vergleichen, werden Sie immer falsch zurückgegeben.
Der folgende Ansatz führt zwei Sätze zu einem zusammen und vergleicht die Größe nur dumm. Wenn es dasselbe ist, ist es dasselbe:
Kopf : Es ist sehr einfach und kurz. Keine externe Bibliothek nur Vanilla JS
Nachteil : Es wird wahrscheinlich langsamer sein, als nur die Werte zu durchlaufen, und Sie benötigen mehr Platz.
quelle
Vergleich zweier Objekte mit ==, ===
Wenn Sie mit
==
oder===
operator zwei Objekte vergleichen, erhalten Sie immer, esfalse
sei denn, diese Objekte verweisen auf dasselbe Objekt . Beispielsweise:Andernfalls entspricht == false, obwohl das Objekt dieselben Werte enthält:
Möglicherweise müssen Sie einen manuellen Vergleich in Betracht ziehen
In ECMAScript 6 können Sie Sets vorher in Arrays konvertieren, um den Unterschied zwischen ihnen zu erkennen:
HINWEIS:
Array.from
ist eine der Standardfunktionen von ECMAScript 6, wird jedoch in modernen Browsern nicht allgemein unterstützt. Überprüfen Sie die Kompatibilitätstabelle hier: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Browser_compatibilityquelle
b
werden, die nicht dabei sinda
?b
nicht anwesend sind,a
besteht darin, zu prüfen, oba.size === b.size
.a.size === b.size
zunächst den Vergleich einzelner Elemente kurz, wenn dies nicht erforderlich ist?has
Operation an Sets aufgrund der Art der Mengen im Gegensatz zurindexOf
Operation an Arrays sehr effizient ausgelegt ist . Daher wäre es sinnvoll, die Filterfunktion zu ändernreturn !b.has(i)
. Dies würde auch die Notwendigkeit einer Konvertierungb
in ein Array beseitigen .Ich habe eine schnelle Polyfüllung für Set.prototype.isEqual () erstellt.
Github Gist - Set.prototype.isEqual
quelle
Basierend auf der akzeptierten Antwort, unter der Annahme der Unterstützung von
Array.from
, ist hier ein Einzeiler:quelle
eqSet = (a,b) => a.size === b.size && [...a].every(b.has.bind(b))
Wenn Mengen nur primitive Datentypen enthalten oder Objekte in Mengen Referenzgleichheit haben, gibt es einen einfacheren Weg
const isEqualSets = (set1, set2) => (set1.size === set2.size) && (set1.size === new Set([...set1, ...set2]).size);
quelle
Ich verfolge diesen Ansatz in Tests:
quelle
a=[1,2,3]
undb=[1,2,3,4]
, dann heißt es, dass sie gleich sind. Also ich denke du brauchst einen zusätzlichen Scheck wiesetA.size === setB.size
Sehr geringfügige Änderung basierend auf der Antwort von @Aadit M Shah:
Wenn jemand anderes ein Problem hat, wie ich es aufgrund einer Eigenart des neuesten Babel getan habe, musste hier eine explizite Bedingung hinzugefügt werden.
(Auch für den Plural finde ich
are
es etwas intuitiver vorzulesen 🙃)quelle
1) Überprüfen Sie, ob die Größen gleich sind. Wenn nicht, sind sie nicht gleich.
2) Iterieren Sie über jedes Element von A und checken Sie das in B vorhandene ein. Wenn eines fehlschlägt, kehren Sie zurück
unequal
3) Wenn die obigen 2 Bedingungen fehlschlagen, bedeutet dies, dass sie gleich sind.
2) Methode 2
quelle
forEach
Methode führt NICHT dazu, dass die übergeordnete Funktion zurückgegeben wird.