Wie kann ich ein ES6 `Set` sortieren?

76

new Set(['b', 'a', 'c']).sort()wirft TypeError: set.sort is not a function. Wie kann ich eine sortieren Set, um eine bestimmte Iterationsreihenfolge sicherzustellen?

ericsoco
quelle
9
Sets sind ungeordnet.
SLaks
2
@SLaks vielleicht sind sie es, aber ich möchte in der Lage sein, den Vorteil der einzigartigen Schlüssel zu nutzen, die Setangeboten werden, und trotzdem die Elemente sortieren zu können. Java bietet SortedSets an , ich kann nur davon ausgehen, dass dies der Fall ist, weil jemand einen gültigen Anwendungsfall angeboten hat ... ES6 sollte nicht Java sein, aber Sortiersätze scheinen nützlich zu sein.
Ericsoco
1
Sie können nicht sort()ein SortedSetentweder. Es wird eine Baumstruktur verwendet, die das Durchlaufen in der Reihenfolge ermöglicht. Sie können diese Reihenfolge jedoch nicht wie bei einer ändernArrayList . Wenn Sie die Reihenfolge ändern möchten, verwenden Sie Listen.
Hat aufgehört - Anony-Mousse
1
Vielleicht müssen einige Nachforschungen angestellt werden, aber ich denke, Setdie Ordnung bleibt erhaltennew Set(['b', 'a', 'c'].sort())
Slai
@Slai ecma-international.org/ecma-262/9.0/index.html#sec-set-objects Ich kann keine Aussage über die Reihenfolge der Elemente finden.
Ceving

Antworten:

136

Eine Menge ist keine geordnete abstrakte Datenstruktur.

A hat Setjedoch immer die gleiche Iterationsreihenfolge - Einfügereihenfolge für Elemente [1]. Wenn Sie es also iterieren (durch eine iterierende Methode, durch Aufrufen Symbol.iteratoroder durch eine for .. of-Schleife), können Sie dies immer erwarten.

Sie können den Satz jederzeit in ein Array konvertieren und sortieren.

Array.from(new Set(["b","a","c"])).sort();
[...(new Set(["b","a","c"]))].sort(); // with spread.

[1] forEachund CreateSetIterator

Benjamin Gruenbaum
quelle
2
Gelöschte meiner eigene Antwort , die das gleiche wie das ist, aber fügt meinen Kommentar zurück: „Ich hoffe , dass jemand wirklich eine Antwort geben kann , die nicht gehen erfordern von Setzu Array. Und zurück Scheint ziemlich ineffizient.“
Ericsoco
12
@ericsoco Die ECMAScript-Spezifikation gibt keine an, OrderedSetaber eine ähnliche Datenstruktur existiert in mehreren anderen Sprachen - normalerweise implementiert durch einen Baum. Sie können eine Userland-Sammlungsbibliothek verwenden, nämlich - die beliebte ImmutableJS bietet eine OrderedSet. In der Tat wird dies in vielen Fällen wahrscheinlich effizienter sein. Wenn Sie also einen Satz mit über 100.000 Elementen haben, würde ich definitiv in Betracht ziehen, stattdessen eine geordnete Satzimplementierung zu verwenden.
Benjamin Gruenbaum
7
Bitte beachten Sie, dass Sie für eine Reihe von Zahlen eine Vergleichsfunktion sortieren müssen : (x, y) => x - y. Andernfalls werden Ihre Nummern lexikografisch sortiert.
Neo
@BenjaminGruenbaum: Ich denke du hast etwas falsch verstanden; nach deren Dokumentation, Immutable.js die OrderedSetverwendet die Einsetzfolge als Iterationsreihenfolge; Das heißt, es macht dasselbe, wie es Ihrer Antwort zufolge der Standard Settut.
Ruakh
@ruakh jedoch ein ImmutableJS OrderedSetObjekt macht Dich zu sortieren lassen () seinen Inhalt, die a) die Norm Set nicht , und b) ist die Funktionalität OP wollte.
Jamie Ridding