Set
Baseline
Weitgehend verfügbar
*
Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit Juli 2015 browserübergreifend verfügbar.
* Einige Teile dieser Funktion werden möglicherweise unterschiedlich gut unterstützt.
Das Set-Objekt ermöglicht es Ihnen, eindeutige Werte jeglichen Typs zu speichern, sei es primitive Werte oder Objektverweise.
Beschreibung
Set-Objekte sind Sammlungen von Werten. Ein Wert im Set darf nur einmal vorkommen; er ist innerhalb der Sammlung des Sets einzigartig. Sie können die Elemente eines Sets in der Einfügereihenfolge durchlaufen. Die Einfügereihenfolge entspricht der Reihenfolge, in der jedes Element erfolgreich mit der add()-Methode in das Set eingefügt wurde (d.h. es gab kein identisches Element im Set, als add() aufgerufen wurde).
Die Spezifikation verlangt, dass Sets so implementiert werden, dass sie im Durchschnitt Zugriffzeiten bieten, die unterlinear zur Anzahl der Elemente in der Sammlung sind. Daher könnte es intern als Hashtabelle (mit O(1) Suche), als Suchbaum (mit O(log(N)) Suche) oder als andere Datenstruktur repräsentiert werden, solange die Komplexität besser als O(N) ist.
Wertekonformität
Die Wertekonformität basiert auf dem SameValueZero-Algorithmus. (Früher wurde SameValue verwendet, das 0 und -0 als unterschiedlich behandelte. Überprüfen Sie die Browser-Kompatibilität.) Das bedeutet, dass NaN als gleich zu NaN angesehen wird (auch wenn NaN !== NaN) und alle anderen Werte gemäß der Semantik des ===-Operators als gleich betrachtet werden. Auch für Objektschlüssel basiert die Gleichheit auf der Objektidentität. Sie werden durch Referenz und nicht durch Wert verglichen. Siehe Verwendung des Set-Objekts für Beispiele.
Leistung
Die has-Methode überprüft, ob ein Wert im Set ist, mit einem Ansatz, der im Durchschnitt schneller ist als das Testen der meisten zuvor zum Set hinzugefügten Elemente. Insbesondere ist sie im Durchschnitt schneller als die Array.prototype.includes-Methode, wenn ein Array eine length hat, die gleich der size eines Sets ist.
Set-Komposition
Das Set-Objekt bietet einige Methoden, mit denen Sie Sets wie bei mathematischen Operationen zusammenstellen können. Diese Methoden umfassen:
| Methode | Rückgabewert | Mathematisches Äquivalent | Venn-Diagramm |
|---|---|---|---|
A.difference(B) |
Set |
||
A.intersection(B) |
Set |
||
A.symmetricDifference(B) |
Set |
||
A.union(B) |
Set |
||
A.isDisjointFrom(B) |
Boolean |
||
A.isSubsetOf(B) |
Boolean |
||
A.isSupersetOf(B) |
Boolean |
Um sie allgemeiner nutzbar zu machen, akzeptieren diese Methoden nicht nur Set-Objekte, sondern alles, das set-ähnlich ist.
Set-ähnliche Objekte
Alle Set-Kompositionsmethoden erfordern, dass this eine tatsächliche Set-Instanz ist, aber ihre Argumente müssen nur set-ähnlich sein. Ein set-ähnliches Objekt ist ein Objekt, das Folgendes bereitstellt:
- Eine
size-Eigenschaft, die eine Zahl enthält. - Eine
has()-Methode, die ein Element nimmt und einen Boolean zurückgibt. - Eine
keys()-Methode, die einen Iterator der Elemente im Set zurückgibt.
Zum Beispiel sind Map-Objekte set-ähnlich, da sie ebenfalls über size, has() und keys() verfügen, sodass sie sich in Set-Methoden wie Mengen von Schlüsseln verhalten:
const a = new Set([1, 2, 3]);
const b = new Map([
[1, "one"],
[2, "two"],
[4, "four"],
]);
console.log(a.union(b)); // Set(4) {1, 2, 3, 4}
Hinweis:
Das set-ähnliche Protokoll ruft die keys()-Methode anstelle von [Symbol.iterator]() auf, um Elemente zu erzeugen. Dies erfolgt, um Karten zu gültigen set-ähnlichen Objekten zu machen, da für Karten der Iterator Einträge erzeugt, die has()-Methode jedoch Schlüssel nimmt.
Arrays sind nicht set-ähnlich, da sie keine has()-Methode oder die size-Eigenschaft haben und ihre keys()-Methode Indizes statt Elemente produziert. WeakSet-Objekte sind ebenfalls nicht set-ähnlich, da sie keine keys()-Methode haben.
Set-ähnliche Browser-APIs
Set-ähnliche Browserobjekte (oder "setlike objects") sind Web-API-Schnittstellen, die sich in vielerlei Hinsicht wie ein Set verhalten.
Genau wie bei Set können die Elemente in der gleichen Reihenfolge durchlaufen werden, in der sie dem Objekt hinzugefügt wurden.
Set-ähnliche Objekte und Set haben auch Eigenschaften und Methoden, die denselben Namen und dasselbe Verhalten teilen.
Im Gegensatz zu Set erlauben sie jedoch nur einen spezifischen vordefinierten Typ für jeden Eintrag.
Die erlaubten Typen sind in der Spezifikation der IDL-Definition festgelegt.
Zum Beispiel ist GPUSupportedFeatures ein set-ähnliches Objekt, das Strings als Schlüssel/Wert verwenden muss.
Dies ist in der Spezifikation IDL unten definiert:
interface GPUSupportedFeatures {
readonly setlike<DOMString>;
};
Set-ähnliche Objekte sind entweder schreibgeschützt oder schreib- und lesbar (siehe das readonly-Schlüsselwort in der oben angegebenen IDL).
- Schreibgeschützte set-ähnliche Objekte haben die Eigenschaft
size, und die Methoden:entries(),forEach(),has(),keys(),values()und[Symbol.iterator](). - Schreibbare set-ähnliche Objekte haben zusätzlich die Methoden:
clear(),delete()undadd().
Die Methoden und Eigenschaften haben dasselbe Verhalten wie die entsprechenden Entitäten in Set, mit Ausnahme der Einschränkung auf die Typen der Einträge.
Folgende sind Beispiele für schreibgeschützte set-ähnliche Browserobjekte:
Folgende sind Beispiele für schreibbare set-ähnliche Browserobjekte:
Konstruktor
Set()-
Erstellt ein neues
Set-Objekt.
Statische Eigenschaften
Set[Symbol.species]-
Die Konstruktionsfunktion, die zum Erstellen von abgeleiteten Objekten verwendet wird.
Instanz-Eigenschaften
Diese Eigenschaften sind auf Set.prototype definiert und werden von allen Set-Instanzen geteilt.
Set.prototype.constructor-
Die Konstruktionsfunktion, die das Instanzobjekt erstellt hat. Für
Set-Instanzen ist der Anfangswert derSet-Konstruktor. Set.prototype.size-
Gibt die Anzahl der Werte im
Set-Objekt zurück. Set.prototype[Symbol.toStringTag]-
Der Anfangswert der
[Symbol.toStringTag]-Eigenschaft ist der String"Set". Diese Eigenschaft wird inObject.prototype.toString()verwendet.
Instanz-Methoden
Set.prototype.add()-
Fügt den angegebenen Wert in dieses Set ein, wenn er nicht bereits vorhanden ist.
Set.prototype.clear()-
Entfernt alle Elemente aus dem
Set-Objekt. Set.prototype.delete()-
Entfernt den angegebenen Wert aus diesem Set, wenn er im Set ist.
Set.prototype.difference()-
Nimmt ein Set und gibt ein neues Set zurück, das Elemente enthält, die in diesem Set, aber nicht im angegebenen Set sind.
Set.prototype.entries()-
Gibt ein neues Iterator-Objekt zurück, das ein Array von
[value, value]für jedes Element imSet-Objekt in Einfügereihenfolge enthält. Dies ist demMap-Objekt ähnlich, sodass der Schlüssel jedes Eintrags mit dem Wert für einSetübereinstimmt. Set.prototype.forEach()-
Ruft
callbackFneinmal für jeden imSet-Objekt vorhandenen Wert in Einfügereihenfolge auf. Wenn einthisArg-Parameter angegeben wird, wird er alsthis-Wert für jeden Aufruf voncallbackFnverwendet. Set.prototype.has()-
Gibt einen Boolean zurück, der angibt, ob der angegebene Wert in diesem
Setvorhanden ist oder nicht. Set.prototype.intersection()-
Nimmt ein Set und gibt ein neues Set zurück, das Elemente enthält, die sowohl in diesem Set als auch im angegebenen Set sind.
Set.prototype.isDisjointFrom()-
Nimmt ein Set und gibt einen Boolean zurück, der anzeigt, ob dieses Set keine gemeinsamen Elemente mit dem gegebenen Set hat.
Set.prototype.isSubsetOf()-
Nimmt ein Set und gibt einen Boolean zurück, der anzeigt, ob alle Elemente dieses Sets im gegebenen Set sind.
Set.prototype.isSupersetOf()-
Nimmt ein Set und gibt einen Boolean zurück, der anzeigt, ob alle Elemente des gegebenen Sets in diesem Set sind.
Set.prototype.keys()-
Ein Alias für
Set.prototype.values(). Set.prototype.symmetricDifference()-
Nimmt ein Set und gibt ein neues Set zurück, das Elemente enthält, die entweder in diesem Set oder im angegebenen Set sind, jedoch nicht in beiden.
Set.prototype.union()-
Nimmt ein Set und gibt ein neues Set zurück, das Elemente enthält, die entweder in diesem Set, dem angegebenen Set oder beiden sind.
Set.prototype.values()-
Gibt ein neues Iterator-Objekt zurück, das die Werte für jedes Element im
Set-Objekt in Einfügereihenfolge erzeugt. Set.prototype[Symbol.iterator]()-
Gibt ein neues Iterator-Objekt zurück, das die Werte für jedes Element im
Set-Objekt in Einfügereihenfolge erzeugt.
Beispiele
>Verwendung des Set-Objekts
const mySet1 = new Set();
mySet1.add(1); // Set(1) { 1 }
mySet1.add(5); // Set(2) { 1, 5 }
mySet1.add(5); // Set(2) { 1, 5 }
mySet1.add("some text"); // Set(3) { 1, 5, 'some text' }
const o = { a: 1, b: 2 };
mySet1.add(o);
mySet1.add({ a: 1, b: 2 }); // o is referencing a different object, so this is okay
mySet1.has(1); // true
mySet1.has(3); // false, since 3 has not been added to the set
mySet1.has(5); // true
mySet1.has(Math.sqrt(25)); // true
mySet1.has("Some Text".toLowerCase()); // true
mySet1.has(o); // true
mySet1.size; // 5
mySet1.delete(5); // removes 5 from the set
mySet1.has(5); // false, 5 has been removed
mySet1.size; // 4, since we just removed one value
mySet1.add(5); // Set(5) { 1, 'some text', {...}, {...}, 5 } - a previously deleted item will be added as a new item, it will not retain its original position before deletion
console.log(mySet1); // Set(5) { 1, "some text", {…}, {…}, 5 }
Sets durchlaufen
Die Iteration über ein Set besucht Elemente in der Einfügereihenfolge.
for (const item of mySet1) {
console.log(item);
}
// 1, "some text", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5
for (const item of mySet1.keys()) {
console.log(item);
}
// 1, "some text", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5
for (const item of mySet1.values()) {
console.log(item);
}
// 1, "some text", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5
// key and value are the same here
for (const [key, value] of mySet1.entries()) {
console.log(key);
}
// 1, "some text", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5
// Convert Set object to an Array object, with Array.from
const myArr = Array.from(mySet1); // [1, "some text", {"a": 1, "b": 2}, {"a": 1, "b": 2}, 5]
// the following will also work if run in an HTML document
mySet1.add(document.body);
mySet1.has(document.querySelector("body")); // true
// converting between Set and Array
const mySet2 = new Set([1, 2, 3, 4]);
console.log(mySet2.size); // 4
console.log([...mySet2]); // [1, 2, 3, 4]
// intersect can be simulated via
const intersection = new Set([...mySet1].filter((x) => mySet2.has(x)));
// difference can be simulated via
const difference = new Set([...mySet1].filter((x) => !mySet2.has(x)));
// Iterate set entries with forEach()
mySet2.forEach((value) => {
console.log(value);
});
// 1
// 2
// 3
// 4
Implementieren grundlegender Mengenoperationen
function isSuperset(set, subset) {
for (const elem of subset) {
if (!set.has(elem)) {
return false;
}
}
return true;
}
function union(setA, setB) {
const _union = new Set(setA);
for (const elem of setB) {
_union.add(elem);
}
return _union;
}
function intersection(setA, setB) {
const _intersection = new Set();
for (const elem of setB) {
if (setA.has(elem)) {
_intersection.add(elem);
}
}
return _intersection;
}
function symmetricDifference(setA, setB) {
const _difference = new Set(setA);
for (const elem of setB) {
if (_difference.has(elem)) {
_difference.delete(elem);
} else {
_difference.add(elem);
}
}
return _difference;
}
function difference(setA, setB) {
const _difference = new Set(setA);
for (const elem of setB) {
_difference.delete(elem);
}
return _difference;
}
// Examples
const setA = new Set([1, 2, 3, 4]);
const setB = new Set([2, 3]);
const setC = new Set([3, 4, 5, 6]);
isSuperset(setA, setB); // returns true
union(setA, setC); // returns Set {1, 2, 3, 4, 5, 6}
intersection(setA, setC); // returns Set {3, 4}
symmetricDifference(setA, setC); // returns Set {1, 2, 5, 6}
difference(setA, setC); // returns Set {1, 2}
Beziehung zu Arrays
const myArray = ["value1", "value2", "value3"];
// Use the regular Set constructor to transform an Array into a Set
const mySet = new Set(myArray);
mySet.has("value1"); // returns true
// Use the spread syntax to transform a set into an Array.
console.log([...mySet]); // Will show you exactly the same Array as myArray
Entfernen duplizierter Elemente aus einem Array
// Use to remove duplicate elements from an array
const numbers = [2, 13, 4, 4, 2, 13, 13, 4, 4, 5, 5, 6, 6, 7, 5, 32, 13, 4, 5];
console.log([...new Set(numbers)]); // [2, 13, 4, 5, 6, 7, 32]
Beziehung zu Strings
// Case sensitive (set will contain "F" and "f")
new Set("Firefox"); // Set(7) [ "F", "i", "r", "e", "f", "o", "x" ]
// Duplicate omission ("f" occurs twice in the string but set will contain only one)
new Set("firefox"); // Set(6) [ "f", "i", "r", "e", "o", "x" ]
Ein Set verwenden, um die Einzigartigkeit einer Liste von Werten sicherzustellen
const array = Array.from(document.querySelectorAll("[id]")).map((e) => e.id);
const set = new Set(array);
console.assert(set.size === array.length);
Spezifikationen
| Spezifikation |
|---|
| ECMAScript® 2027 Language Specification> # sec-set-objects> |