01 · Problem
Wofür braucht man das?
Set-Algebra wird in Anwendungscode oft mit wiederholten Schleifen und leicht verwechselter Differenzrichtung nachgebaut.
02 · Denkmodell
Das mentale Modell
Ein Set beschreibt Mitgliedschaft. Union, Intersection und Difference sollten als reine Operationen mit eindeutiger Links-rechts-Richtung lesbar sein.
Demonstriert Vereinigung, Schnittmenge und den bestehenden gerichteten Differenzvertrag. except berechnet Argument minus Empfänger. Die Richtung bleibt erhalten und ist durch Tests festgehalten.
03 · Kontrollfluss
Was passiert in welcher Reihenfolge?
- Zwei Iterables als linke und rechte Menge auffassen.
- Für jede Operation die Richtung ausdrücklich festlegen.
- Mit has in linearer Zeit Mitgliedschaft prüfen.
- Ein neues Set zurückgeben, sofern Mutation nicht Teil des Namens ist.
04 · Bauteile
Die entscheidenden Verträge
merge / both / except / filterBerechnet Vereinigung, Schnittmenge, Argument-minus-Empfänger-Differenz und Filterung.05 · Selbst bauen
Selbst implementieren
Implementiere mathematische Operationen zunächst als pure Funktionen; mutierende Kurzformen können später bewusst ergänzt werden.
- Akzeptiere Iterable für Union und ReadonlySet für schnelle Mitgliedschaftstests.
- Definiere difference(left, right) immer als Werte aus left, die nicht in right liegen.
- Gib durchgehend denselben Collection-Typ zurück.
class SetOps<T> extends Set<T> {
union(other: Iterable<T>) {
return new SetOps([...this, ...other]);
}
intersection(other: ReadonlySet<T>) {
return new SetOps([...this].filter(value => other.has(value)));
}
difference(other: ReadonlySet<T>) {
return new SetOps([...this].filter(value => !other.has(value)));
}
}06 · Verifizieren
Was solltest du testen?
- Leere, identische und disjunkte Sets liefern die mathematisch erwarteten Ergebnisse.
- difference(A, B) und difference(B, A) werden separat geprüft.
- Objekte folgen dokumentiert Referenzgleichheit und Eingaben bleiben unverändert.
Selbst ausprobieren
Formuliere die erste Prüfaussage als fehlschlagenden Test, implementiere die kleinste Korrektur und ergänze einen Grenzfall.
Leere, identische und disjunkte Sets liefern die mathematisch erwarteten Ergebnisse.
Ansatz vergleichen
Dein Test sollte beim gezielten Verletzen der Invariante fehlschlagen und nach der Korrektur wieder bestehen. Halte den Aufbau deterministisch und prüfe ein beobachtbares Ergebnis.
07 · Grenzen
Kompromisse und Stolperfallen
- Native Set-Gleichheit ist SameValueZero, keine strukturelle Objektgleichheit.
- Immutable Ergebnisse benötigen zusätzliche Allokationen, sind aber leichter zu komponieren.
except berechnet Argument minus Empfänger. Die Richtung bleibt erhalten und ist durch Tests festgehalten.
08 · Weiterdenken
Quellcode und verwandte Ideen
yarn tsx packages/better-set/examples/basic.ts