Start · Sprachen · JavaScript · Referenz · Set.prototype.symmetricDifference()

Set.prototype.symmetricDifference()

Methode

Gibt eine neue <code>Set</code> zurück, die alle Elemente enthält, die in genau einer der beiden Mengen vorkommen, also in dieser oder in <code>other</code>, aber nicht in beiden.

seit JavaScript ES2025 (Baseline 2024: Chrome 122, Firefox 127, Sa Kategorie: method-property

Signatur

Set.prototype.symmetricDifference(other)

Beschreibung

symmetricDifference() berechnet die symmetrische Differenz zweier Mengen, mathematisch A △ B bzw. (A \ B) ∪ (B \ A). Heraus kommt eine neue Set mit allen Elementen, die nur in einer der beiden Mengen stehen. Elemente, die in beiden vorkommen, fallen weg. Die ursprüngliche Menge und das Argument bleiben unverändert.

Die Methode eignet sich gut, um Änderungen zwischen zwei Zuständen zu finden, etwa welche Rechte, Tags oder ausgewählten Einträge hinzugekommen oder weggefallen sind. Die Richtung spielt dabei keine Rolle. Wer wissen will, was hinzugekommen und was entfernt wurde, braucht stattdessen zweimal difference().

Das Argument other muss keine echte Set sein. Es genügt ein set-ähnliches Objekt mit einer numerischen Eigenschaft size sowie den Methoden has() und keys(), zum Beispiel eine Map (dann zählen ihre Schlüssel). Arrays sind nicht set-ähnlich und müssen erst mit new Set(array) umgewandelt werden.

Elemente werden wie überall bei Set mit dem Algorithmus SameValueZero verglichen: NaN gilt als gleich NaN, und +0 gleich -0. Objekte werden über ihre Referenz verglichen, nicht über ihren Inhalt. Die Reihenfolge im Ergebnis ist: zuerst die Elemente aus dieser Menge, die nicht in other stehen, danach die neuen Elemente aus other.

Parameter

Name Typ Default Beschreibung
$other Pflicht Set | Map | set-ähnliches Objekt Die zweite Menge. Sie muss size (Zahl), has(value) und keys() (liefert einen Iterator) bereitstellen. Fehlen diese oder ist size NaN, wird ein TypeError geworfen.

Rückgabewert

Typ
Set
Beschreibung
Eine neue Set-Instanz mit allen Elementen, die in genau einer der beiden Mengen vorkommen.

Beispiele

Grundprinzip: Elemente in genau einer Menge

const gerade = new Set([2, 4, 6, 8]);
const quadrate = new Set([1, 4, 9]);

const ergebnis = gerade.symmetricDifference(quadrate);
console.log([...ergebnis]);
// Die Operation ist symmetrisch, die Reihenfolge der Elemente aber nicht:
console.log([...quadrate.symmetricDifference(gerade)]);
[2, 6, 8, 1, 9] [1, 9, 2, 6, 8]

Geänderte Checkbox-Auswahl erkennen

const gespeichert = new Set(['newsletter', 'sms', 'push']);
const aktuell = new Set(['newsletter', 'email', 'push']);

const geaendert = gespeichert.symmetricDifference(aktuell);

if (geaendert.size > 0) {
  console.log(`Ungespeicherte Änderungen bei: ${[...geaendert].join(', ')}`);
}
Ungespeicherte Änderungen bei: sms, email

Arrays und Map als Argument

const tagsA = ['js', 'css', 'html'];
const tagsB = ['js', 'node'];

// Arrays erst in Set umwandeln – ein Array direkt übergeben wirft einen TypeError
const diff = new Set(tagsA).symmetricDifference(new Set(tagsB));
console.log([...diff]);

// Eine Map ist set-ähnlich; verglichen werden ihre Schlüssel
const preise = new Map([['css', 10], ['sass', 20]]);
console.log([...new Set(tagsA).symmetricDifference(preise)]);
['css', 'html', 'node'] ['js', 'html', 'sass']

Polyfill-artiger Fallback für ältere Umgebungen

const symDiff = (a, b) =>
  typeof a.symmetricDifference === 'function'
    ? a.symmetricDifference(b)
    : new Set([...[...a].filter((x) => !b.has(x)), ...[...b].filter((x) => !a.has(x))]);

console.log([...symDiff(new Set([1, 2, 3]), new Set([3, 4]))]);
[1, 2, 4]

// Wichtig · Fallstricke

  • Kompatibilität: Die Methode ist neu (ES2025, Baseline seit Mitte 2024). Sie fehlt in Node.js < 22, Chrome < 122, Firefox < 127 und Safari < 17. Für ältere Umgebungen braucht man ein Polyfill (z. B. core-js) oder einen eigenen Fallback.
  • Keine Arrays als Argument: set.symmetricDifference([1, 2]) wirft einen TypeError, weil Arrays keine size-Eigenschaft haben. Vorher mit new Set(array) umwandeln.
  • Objekte werden über die Referenz verglichen: Zwei inhaltlich gleiche Objekte wie {id: 1} gelten als verschiedene Elemente. Für Vergleiche nach Inhalt besser Primitive speichern, etwa IDs.
  • Reihenfolge: Mathematisch gilt a.symmetricDifference(b) gleich b.symmetricDifference(a), aber die Reihenfolge beim Durchlaufen unterscheidet sich.
  • Unterklassen: Das Ergebnis ist immer eine einfache Set, auch wenn die Methode auf einer Unterklasse von Set aufgerufen wird. Es wird kein Symbol.species verwendet.
  • Anders als bei difference() oder intersection() wird other hier immer vollständig über keys() durchlaufen. Die Laufzeit hängt also von beiden Mengengrößen ab.