Set

Unter einem Set (deutsch Menge) versteht man eine Datenstruktur ähnlich einer Liste, in der jedoch ein Wert nur einmal vorkommen darf.

Ein Set erstellt man über die Konstruktorfunktion. Als Wert kann man ein Iterierbares Objekt übergeben. Wenn man ein solches Objekt an new Set() übergibt, "geht" das Set durch jedes einzelne Element dieses Objekts und fügt es seiner Sammlung hinzu (und filtert dabei automatisch Duplikate heraus). Die Werte werden wie der === Operator auf strikte Gleichheit überprüft.

Beispiel Zeichenkette Länge / Beispiel Alphabet / Beispiel Liste

Hier ist eine Liste der gängigsten iterierbaren Objekte, die du einem Set übergeben kannst:

1. Arrays (Der Klassiker)

Jedes Element des Arrays wird zu einem Eintrag im Set.

JavaScript
const meinSet = new Set([1, 2, 2, 3]); // Ergebnis: {1, 2, 3}  

2. Strings (Zeichenketten)

Ein String ist in JavaScript iterierbar – er wird Zeichen für Zeichen durchlaufen. Das ist extrem nützlich, um zum Beispiel alle vorkommenden Buchstaben in einem Wort ohne Dopplungen zu finden.

JavaScript
const buchstaben = new Set("Mississippi");   // Ergebnis: {"M", "i", "s", "p"}  

3. NodeLists & HTMLCollections

Wenn du im Browser mehrere Elemente selektierst (z. B. mit querySelectorAll), erhältst du eine NodeList. Diese kannst du direkt in ein Set werfen.

JavaScript
const buttons = document.querySelectorAll("button");
const buttonSet = new Set(buttons);  

4. Arguments-Objekt

In klassischen Funktionen (nicht Arrow-Functions) gibt es das arguments-Objekt, das alle übergebenen Parameter enthält. Auch das ist iterierbar.

JavaScript
function listeSammeln() {
    const argumentSet = new Set(arguments);
    console.log(argumentSet);
  }  
listeSammeln("A", "B", "A"); // Ergebnis: {"A", "B"}  

5. Andere Sets und Maps

Du kannst ein bestehendes Set einem neuen Set übergeben (um eine Kopie zu erstellen) oder die .keys(), .values() oder .entries() einer Map übergeben.

JavaScript
const map = new Map([["a", 1], ["b", 2]]);
const mapKeys = new Set(map.keys()); // Ergebnis: {"a", "b"}  

6. TypedArrays

Spezielle Arrays für binäre Daten (wie Int32Array oder Uint8Array), die oft in der Spieleprogrammierung oder bei Grafikberechnungen vorkommen, funktionieren ebenfalls.

Warum ist das wichtig?

Der Set-Konstruktor erwartet genau ein Argument, und dieses muss das Iterable-Protokoll unterstützen.

Wichtig: Ein normales Objekt {a: 1, b: 2} ist nicht direkt iterierbar! Wenn du versuchst, new Set({a: 1, b: 2}) zu schreiben, erhälst du einen Fehler (TypeError: object is not iterable). Um die Werte eines Objekts in ein Set zu bekommen, müsstest du new Set(Object.values(meinObjekt)) nutzen, da Object.values() wiederum ein Array (und damit ein Iterable) zurückgibt.

Das ist genau das "Schachtel-Prinzip", das es beim Spread-Operator gibt: Das Set öffnet die Schachtel (das Iterable), nimmt den Inhalt raus und sortiert ihn ein.

Ein Set in JavaScript ist im Vergleich zu einem Array recht "schlank" und spezialisiert. Es hat nur eine Handvoll Methoden, die aber sehr effizient sind, weil ein Set intern so optimiert ist, dass es extrem schnell prüfen kann, ob ein Wert vorhanden ist.

Hier sind die wichtigsten Methoden im Überblick:

Die Methoden-Liste

Methode / Eigenschaft Beschreibung
add(wert) Fügt ein Element hinzu (falls es noch nicht existiert).
has(wert) Prüft, ob ein Wert vorhanden ist (gibt true oder false zurück).
delete(wert) Entfernt ein spezifisches Element.
clear() Löscht alle Elemente aus dem Set.
size (Eigenschaft) Gibt an, wie viele Elemente im Set sind.

Ein praxisnahes Beispiel: Die Gästeliste

Stell dir vor, du verwaltest eine Gästeliste für eine Party. Du willst sicherstellen, dass niemand doppelt auf der Liste steht und schnell prüfen können, ob jemand eingeladen ist.
Beispiel

JavaScript
// 1. Ein leeres Set erstellen
      const gaesteListe = new Set();

      // 2. add() - Gäste hinzufügen
      gaesteListe.add( "Michael" );
      gaesteListe.add( "Sarah" );
      gaesteListe.add( "Michael" ); // Wird ignoriert, da Michael schon da ist

      // 3. size - Wie viele sind auf der Liste?
      console.log( gaesteListe.size ); // 2

      // 4. has() - Schnell prüfen
      if ( gaesteListe.has( "Sarah" ) )
      {
        console.log( "Sarah ist eingeladen!" );
      }

      // 5. delete() - Jemand sagt ab
      gaesteListe.delete( "Michael" );
      console.log( gaesteListe.has( "Michael" ) ); // false

      // 6. forEach() - Die Liste durchgehen
      gaesteListe.forEach( gast =>
      {
        console.log( "Willkommen, " + gast );
      } );

      // 7. clear() - Die Party ist vorbei
      gaesteListe.clear();
      console.log( gaesteListe.size ); // 0

Ein technisches Beispiel: Farbauswahl beim Design

In der Webseitengestaltung, könnte ein Set nützlich sein, um alle verwendeten Farben in einem Projekt zu sammeln, ohne Dubletten zu haben:

Beispiel

JavaScript
  const benutzteFarben = new Set(["#ff0000", "#00ff00", "#ff0000"]); //Rot ist doppelt 
     function registriereFarbe(neueFarbe) {
          if (benutzteFarben.has(neueFarbe)) {
                  console.log(`Die Farbe ${neueFarbe} wurde bereits verwendet.`);
              } else {
                      benutzteFarben.add(neueFarbe);
                      console.log(`Farbe ${neueFarbe} zur Palette hinzugefügt.`);
              }
      }
registriereFarbe("#0000ff"); // Blau hinzufügen
registriereFarbe("#ff0000"); // Hinweis, dass Rot schon existiert
            

Warum has() besser ist als includes()

Wenn du ein Array mit 10.000 Einträgen hast und mit .includes() suchst, muss JavaScript im schlimmsten Fall alle 10.000 Einträge nacheinander anschauen. Ein Set nutzt einen internen Index (ähnlich wie ein Inhaltsverzeichnis), wodurch .has() nahezu blitzschnell ist, egal wie groß das Set ist.

Das ist besonders bei deinen Projekten mit vielen Daten ein echter Performance-Vorteil!