`Set`-Objekt
Dieser Artikel erklärt das Set-Objekt.
Wir erklären das Set-Objekt anhand praktischer Beispiele.
YouTube Video
Set-Objekt
Set ist ein eingebautes Objekt, das zum Verwalten von Sammlungen einzigartiger, nicht doppelter Werte verwendet wird. Es ermöglicht eine einfachere Duplikatentfernung und Existenzüberprüfung als mit Arrays und erleichtert die Implementierung von Mengenoperationen wie Vereinigung und Schnittmenge.
Grundlagen: Erstellen und Verwenden von Sets
Schauen wir uns zunächst an, wie man ein Set erstellt, Elemente hinzufügt und entfernt, auf Existenz prüft und die Größe eines Sets abruft.
Unten finden Sie ein einfaches Beispiel, das ein neues Set erstellt und die Methoden add, has, delete sowie size demonstriert.
1// Create a Set and demonstrate add, has, delete, and size
2const s = new Set();
3
4s.add(1);
5s.add(2);
6s.add(2); // duplicate, ignored
7
8console.log(s.has(1)); // true
9console.log(s.has(3)); // false
10
11s.delete(2);
12console.log(s.size); // 1
13
14console.log([...s]); // [1]
- Wie in diesem Code gezeigt, entfernt
Setautomatisch doppelte primitive Werte, und Sie können die Anzahl der Elemente mitsizeabrufen.
Iterationsmethoden
Set ist iterierbar, daher können Sie mit for...of oder forEach darüber iterieren. Die Reihenfolge entspricht der Einfügereihenfolge.
Hier sind typische Anwendungsbeispiele für for...of und forEach.
1// Iterate a Set with for...of and forEach
2const s = new Set(['a', 'b', 'c']);
3
4for (const v of s) {
5 console.log('for...of:', v);
6}
7
8s.forEach((value, sameValue, setRef) => {
9 // Note: second arg is same as first for Set API to match Map signature
10 console.log('forEach:', value);
11});- Die Callback-Signatur für
forEachlautetvalue, value, set(aus Kompatibilitätsgründen mit Map), aber meist benötigt man nur das erste Argumentvalue.
Umwandlung zwischen Arrays und Sets (nützlich zur Duplikatentfernung)
Hier wird eine einfache Methode gezeigt, um Duplikate aus einem Array zu entfernen und wie man ein Set wieder in ein Array umwandelt.
Unten finden Sie ein Beispiel, wie Duplikate aus einem Array entfernt werden, indem es durch ein Set übergeben wird.
1// Deduplicate an array using Set
2const arr = [1, 2, 2, 3, 3, 3];
3const deduped = [...new Set(arr)];
4console.log(deduped); // [1, 2, 3]
5
6// Convert a Set to an array using Array.from
7const s = new Set([4, 5, 6]);
8const arrFromSet = Array.from(s);
9console.log(arrFromSet); // [4, 5, 6]
- Dieses Muster ist kurz und schnell, daher wird es häufig zum Entfernen von Duplikaten in Arrays verwendet. Es ist besonders effektiv bei primitiven Werten.
Objekte und Referenzbehandlung
Objekte in einem Set werden nach Referenz verglichen, sodass verschiedene Instanzen mit gleichem Inhalt als unterschiedliche Elemente betrachtet werden.
Der folgende Code zeigt, was passiert, wenn Sie Objekte zu einem Set hinzufügen.
1// Objects are compared by reference in a Set
2const obj1 = { x: 1 };
3const obj2 = { x: 1 };
4
5const s = new Set();
6s.add(obj1);
7s.add(obj2);
8
9console.log(s.size); // 2 (different references)
10console.log(s.has(obj1)); // true
11console.log(s.has({ x: 1 })); // false (different object)
- Die Duplikaterkennung bei Objekten basiert auf Referenzidentität. Wenn Sie nur nach dem Objektinhalt deduplizieren wollen, müssen Sie sie serialisieren oder anderweitig verarbeiten.
Sonderwerte: Behandlung von NaN und -0/+0
Set verwendet die Same-value-zero-Vergleichsregel, um Wertgleichheit zu bestimmen. Diese Vergleichsmethode weist bei Zahlen folgende Merkmale auf:.
NaNwird als gleich zuNaNbetrachtet.- Positives
+0und negatives-0werden nicht unterschieden und als gleicher Wert behandelt.
Daher tritt beim Hinzufügen dieser Werte zu einem Set folgendes Verhalten auf:.
1// NaN and zero behavior in Set
2const s = new Set();
3
4s.add(NaN);
5s.add(NaN);
6console.log(s.size); // 1 (NaN considered the same)
7
8s.add(+0);
9s.add(-0);
10console.log(s.size); // still 2 (NaN + 0)
11console.log([...s]); // [NaN, 0] (order may vary but only one zero)
- Beim normalen Vergleich (
NaN === NaN) ergibt sichfalse, aber innerhalb einesSetgelten alleNaN-Werte als „gleicher Wert“. - +0 und -0 sind mathematisch unterscheidbar, werden aber in einem
Seteinfach als0behandelt. - Daher bleibt im
Setjeweils nur einNaNund ein0übrig. - Die Vergleichsregel des
Setist ähnlich wie beiObject.is, aber nicht genau gleich.Object.is(+0, -0)gibtfalsezurück, aber in einemSetwerden sie als identisch betrachtet. Bitte beachten Sie diesen Unterschied.
Typische Anwendung: Mengenoperationen (Vereinigung, Schnittmenge, Differenz)
Mengenoperationen lassen sich mit Set deutlich übersichtlicher schreiben. Unten finden Sie typische Implementierungsbeispiele.
Hier sind Beispiele für Funktionen für union, intersection und difference.
1// Set operations: union, intersection, difference
2function union(a, b) {
3 return new Set([...a, ...b]);
4}
5
6function intersection(a, b) {
7 return new Set([...a].filter(x => b.has(x)));
8}
9
10function difference(a, b) {
11 return new Set([...a].filter(x => !b.has(x)));
12}
13
14// Demo
15const A = new Set([1, 2, 3]);
16const B = new Set([3, 4, 5]);
17
18console.log('union', [...union(A, B)]); // [1,2,3,4,5]
19console.log('intersection', [...intersection(A, B)]); // [3]
20console.log('difference A\\B', [...difference(A, B)]); // [1,2]
- Mengenoperationen können einfach geschrieben werden, indem man Filter mit der Kombination aus
Setund Arrays verwendet. Beim Arbeiten mit großen Datenmengen sorgt die O(1)-Performance vonhasfür schnellere Operationen.
Praktisches Beispiel: Ermitteln von Unterschieden zwischen Arrays (Erkennen hinzugefügter/entfernter Elemente)
Das folgende Beispiel zeigt, wie man ein Set verwendet, um den Unterschied zwischen zwei Arrays (alter und neuer Liste) zu ermitteln. So können Sie erkennen, welche Elemente hinzugefügt und welche entfernt wurden.
1// Find added and removed items between two arrays
2function diffArrays(oldArr, newArr) {
3 const oldSet = new Set(oldArr);
4 const newSet = new Set(newArr);
5
6 const added = [...newSet].filter(x => !oldSet.has(x));
7 const removed = [...oldSet].filter(x => !newSet.has(x));
8
9 return { added, removed };
10}
11
12const oldList = [1, 2, 3];
13const newList = [2, 3, 4, 5];
14
15console.log(diffArrays(oldList, newList));
16// { added: [4,5], removed: [1] }
- Diese Methode ist sehr praktisch, um Unterschiede in ID-Listen, Tag-Listen und ähnlichen Fällen zu erkennen. Die Anwendung ist bei primitiven Werten am einfachsten.
Unterschiede zwischen WeakSet und Set (Speicherverwaltung)
WeakSet ist ähnlich wie Set, verwendet jedoch schwache Referenzen, sodass seine Elemente vom Garbage Collector entfernt werden können. Das Folgende zeigt grundlegende Verwendungen von WeakSet.
1// WeakSet basics (objects only, not iterable)
2const ws = new WeakSet();
3let obj = { id: 1 };
4ws.add(obj);
5
6console.log(ws.has(obj)); // true
7
8obj = null; // Now the object is eligible for GC; WeakSet won't prevent collection
WeakSet kann nur Objekte enthalten und ist nicht iterierbar. Im Folgenden finden Sie Beispiele für die Einschränkungen von WeakSet – es speichert nur Objekte und ist nicht iterierbar.
1// WeakSet basics (objects only, not iterable)
2const ws = new WeakSet();
3
4// --- Only objects can be added ---
5try {
6 ws.add(1); // number
7} catch (e) {
8 console.log("Error: WeakSet can only store objects. Adding a number is not allowed.");
9}
10
11try {
12 ws.add("text"); // string
13} catch (e) {
14 console.log("Error: WeakSet can only store objects. Adding a string is not allowed.");
15}
16
17// --- WeakSet is not iterable ---
18try {
19 for (const value of ws) {
20 console.log(value);
21 }
22} catch (e) {
23 console.log("Error: WeakSet is not iterable. You cannot use for...of to loop over its elements.");
24}
25
26// --- Cannot convert to array ---
27try {
28 console.log([...ws]);
29} catch (e) {
30 console.log("Error: WeakSet cannot be converted to an array because it does not support iteration.");
31}
32
33// The object becomes eligible for garbage collection
34let obj = { id: 1 };
35ws.add(obj);
36obj = null;WeakSetist nützlich, um das Vorhandensein von Objekten vorübergehend zu verfolgen, aber Sie können seine Elemente nicht aufzählen oder seine Größe ermitteln.
Leistung und Auswahl des Einsatzzeitpunkts
Bei der Entscheidung, ob Sie ein Set verwenden möchten, ist es wichtig, dessen Leistungsmerkmale und die Art Ihrer Daten zu verstehen.
has,addunddeletearbeiten im Durchschnitt typischerweise mit einer nahezu O(1)-Leistung. Daher istSetin Szenarien, in denen Sie häufig auf Existenz prüfen oder Duplikate entfernen, Arrays häufig überlegen.- Seien Sie vorsichtig, wenn Sie Objekte anhand ihres Inhalts (Werte) deduplizieren möchten. Da
Setnach Referenz vergleicht, empfiehlt es sich in der Praxis, IDs oder andere Schlüssel zu verwenden, oder Objekte vor der Verwendung von Sets in primitive Werte zu serialisieren, wenn ein wertbasierter Vergleich erforderlich ist. Setist besonders nützlich, um die Lesbarkeit des Codes bei kleinen bis mittelgroßen Sammlungen zu verbessern. Wenn Sie hingegen eine sehr große Anzahl von Elementen verwalten oder häufig zwischen Arrays und Sets konvertieren, wird empfohlen, tatsächlich Benchmarks und Tests durchzuführen.
Häufige Fallstricke
Set ist praktisch, aber wenn Sie seine Spezifikation nicht kennen, können unerwartete Verhaltensweisen für Verwirrung sorgen. Hier sind einige typische Punkte, auf die Sie achten sollten:.
- Objekte werden nach Referenz verglichen, sodass selbst bei gleichem Inhalt verschiedene Objekte nicht als Duplikate erkannt werden.
Setbewahrt die Einfügereihenfolge, aber Sie können nicht wie bei Arrays per Index auf Elemente zugreifen. Wenn Sie den Indexzugriff nutzen möchten, wandeln Sie dasSetzunächst in ein Array um.WeakSetkann nicht aufgezählt werden und kann nur Objekte speichern. Beachten Sie, dass die Einsatzmöglichkeiten begrenzt sind.NaNwird als gleicher Wert behandelt und+0sowie-0werden nicht unterschieden. Dies liegt an der Same-value-zero-Vergleichsregel.
Zusammenfassung
Set ist eine praktische Datenstruktur, mit der Sie Sammlungen von einzigartigen Werten intuitiv verarbeiten können. Sie können damit Duplikate aus Arrays entfernen, schnelle Existenzprüfungen durchführen oder Mengenoperationen wie Vereinigung und Schnittmenge mit einfach lesbarem Code umsetzen.
Andererseits sind zusätzliche Maßnahmen erforderlich, wenn Sie aufgrund des Vergleichs nach Referenz die Gleichheit von Objekten anhand ihres Inhalts bestimmen möchten.
Wenn Sie diese Eigenschaften verstehen und richtig einsetzen, ist Set eine leistungsstarke Option zur Verbesserung der Lesbarkeit und Wartbarkeit Ihres Codes.
Sie können den obigen Artikel mit Visual Studio Code auf unserem YouTube-Kanal verfolgen. Bitte schauen Sie sich auch den YouTube-Kanal an.