Ich möchte ein Array von ungefähr 200-300 Objekten sortieren, wobei ich nach einem bestimmten Schlüssel und einer bestimmten Reihenfolge (auf / ab) sortiere. Die Reihenfolge der Ergebnisse muss konsistent und stabil sein.
Was wäre der beste Algorithmus, und könnten Sie ein Beispiel für die Implementierung in Javascript geben?
Vielen Dank!
javascript
algorithm
sorting
William Casarin
quelle
quelle
Antworten:
Es ist möglich, eine stabile Sortierung von einer nicht stabilen Sortierfunktion zu erhalten.
Vor dem Sortieren erhalten Sie die Position aller Elemente. Wenn in Ihrer Sortierbedingung beide Elemente gleich sind, sortieren Sie nach der Position.
Tada! Du hast eine stabile Sorte.
Ich habe in meinem Blog einen Artikel darüber geschrieben, wenn Sie mehr über diese Technik und deren Implementierung erfahren möchten: http://blog.vjeux.com/2010/javascript/javascript-sorting-table.html
quelle
Da Sie nach etwas Stabilem suchen, sollte die Zusammenführungssortierung ausreichen.
http://www.stoimen.com/blog/2010/07/02/friday-algorithms-javascript-merge-sort/
Der Code ist auf der oben genannten Website zu finden:
BEARBEITEN:
Laut diesem Beitrag sieht es so aus, als ob Array.Sort in einigen Implementierungen eine Zusammenführungssortierung verwendet.
quelle
Array#shift
Kann in O (n) Zeit und damitmerge
in O (n * n) arbeiten.Etwas kürzere Version derselben Sache mit ES2017-Funktionen wie Pfeilfunktionen und Destrukturierung:
Funktion
Es akzeptiert Eingabearrays und Vergleichsfunktionen:
Es gibt auch ein neues Array zurück, anstatt eine direkte Sortierung wie die integrierte Funktion Array.sort () vorzunehmen .
Prüfung
Wenn wir das folgende
input
Array nehmen, zunächst sortiert nachweight
:Dann sortieren Sie es
height
mitstableSort
:Ergebnisse in:
Sortieren des gleichen
input
Arrays mithilfe des integrierten ArraysArray.sort()
(in Chrome / NodeJS):Kehrt zurück:
Ressourcen
Aktualisieren
quelle
stableSort
Funktion ist eine wirklich gute Lösung!Ich weiß, dass diese Frage seit einiger Zeit beantwortet wurde, aber ich habe zufällig eine gute stabile Implementierung für die Zusammenführungssortierung für Array und jQuery in meiner Zwischenablage. Daher werde ich sie in der Hoffnung teilen, dass einige zukünftige Suchende sie nützlich finden könnten.
Hier können Sie Ihre eigene Vergleichsfunktion wie gewohnt angeben
Array.sort
Implementierung .Implementierung
Beispiel Verwendung
quelle
array.sort
, siehe Test hier für Zeichenfolgen und Ganzzahlen -> jsfiddle.net/QC64jmergeSort
und nichtsort
, daher ist sie nicht als Ersatz gedacht. Manchmal benötigen Sie nur eine stabile Zusammenführungssortierung, z. B. beim Sortieren von Tabellen nach Spalten.Sie können die folgende Polyfüllung verwenden, um eine stabile Sortierung unabhängig von der nativen Implementierung zu implementieren, basierend auf der in dieser Antwort gemachten Aussage :
Das Ausführen der oben implementierten Leistungstests
stableSort()
scheint mit etwa 57% der Geschwindigkeit vonsort()
Chrome Version 59-61 zu laufen .Durch
.bind(compareFunction)
die Verwendung der verpackten anonymen Funktion in wurdestableSort()
die relative Leistung von etwa 38% gesteigert, indemcompareFunction
bei jedem Aufruf ein nicht benötigter Verweis auf den Gültigkeitsbereich vermieden wurde, indem sie stattdessen dem Kontext zugewiesen wurde .Aktualisieren
Der ternäre Operator wurde in einen logischen Kurzschluss geändert, der im Durchschnitt tendenziell besser abschneidet (scheint einen Wirkungsgradunterschied von 2-3% zu bewirken).
quelle
Im Folgenden wird das bereitgestellte Array sortiert, indem die bereitgestellte Vergleichsfunktion angewendet wird und der ursprüngliche Indexvergleich zurückgegeben wird, wenn die Vergleichsfunktion 0 zurückgibt:
Im folgenden Beispiel wird ein Array von Namen nach Nachnamen sortiert, wobei die Reihenfolge der gleichen Nachnamen beibehalten wird:
quelle
jQuery.expando.split( "" ).sort( ( a, b ) => 0 ).join( "" ) === jQuery.expando
Hier ist eine stabile Implementierung. Es funktioniert mit der nativen Sortierung. In Fällen, in denen Elemente als gleich verglichen werden, unterbrechen Sie die Verknüpfungen anhand der ursprünglichen Indexposition.
ein nicht gründlicher Test
eine andere Antwort darauf an, postete aber nicht den Codez.
Aber es ist nicht schnell nach meinem Benchmark . Ich habe ein Merge-Sort-Impl so geändert , dass es eine benutzerdefinierte Komparatorfunktion akzeptiert, und es war viel schneller.
quelle
Sie können auch Timsort verwenden. Dies ist ein wirklich komplizierter Algorithmus (mehr als 400 Zeilen, daher hier kein Quellcode). Sehen Sie sich also die Beschreibung von Wikipedia an oder verwenden Sie eine der vorhandenen JavaScript-Implementierungen:
GPL 3-Implementierung . Verpackt als Array.prototype.timsort. Scheint eine exakte Umschreibung von Java-Code zu sein.
Public Domain Implementierung Beispiel gedacht, zeigt der Beispielcode nur die Verwendung mit Ganzzahlen.
Timsort ist eine hochoptimierte Mischung aus Mergesort und Shuffle-Sortierung und der Standardsortieralgorithmus in Python und Java (1.7+). Es ist ein komplizierter Algorithmus, da er für viele Sonderfälle unterschiedliche Algorithmen verwendet. Infolgedessen ist es unter den unterschiedlichsten Umständen extrem schnell.
quelle
Ein einfacher mergeSort von http://www.stoimen.com/blog/2010/07/02/friday-algorithms-javascript-merge-sort/
quelle
Ich muss mehrdimensionale Arrays nach einer beliebigen Spalte und dann nach einer anderen sortieren. Ich benutze diese Funktion, um zu sortieren:
Beachten Sie, dass ary.sort niemals Null zurückgibt. Hier treffen einige Implementierungen der Funktion "sort" Entscheidungen, die möglicherweise nicht richtig sind.
Das ist auch verdammt schnell.
quelle
Hier erfahren Sie, wie Sie das JS-Standardarrayobjekt mit einer Prototypmethode unter Verwendung von MERGE SORT erweitern können . Diese Methode ermöglicht das Sortieren nach einem bestimmten Schlüssel (erster Parameter) und einer bestimmten Reihenfolge ('asc' / 'desc' als zweiter Parameter).
Sie können dies selbst testen, indem Sie das obige Snippet in Ihre Browserkonsole ablegen und dann versuchen:
Oder Reihenfolge basierend auf einem bestimmten Feld in einem Array von Objekten:
quelle
Ich brauchte also eine stabile Sortierung für meine React + Redux-App, und die Antwort von Vjeux hier hat mir geholfen. Meine (generische) Lösung scheint sich jedoch von den anderen zu unterscheiden, die ich bisher hier sehe. Ich teile sie daher, falls jemand anderes einen passenden Anwendungsfall hat:
sort()
API haben, wo ich eine Komparatorfunktion übergeben kann.Meine Lösung besteht darin, ein typisiertes Array von zu erstellen
indices
und dann eine Vergleichsfunktion zu verwenden, um diese Indizes basierend auf dem zu sortierenden Array zu sortieren. Dann können wir die sortierten verwendenindices
entweder Art des Original - Array oder eine sortierte Kopie in einem einzigen Durchgang erstellen. Wenn das verwirrend ist, denken Sie so: Wo Sie normalerweise eine Vergleichsfunktion übergeben würden wie:Sie verwenden jetzt stattdessen:
Geschwindigkeit ist gut; Es handelt sich im Grunde genommen um den integrierten Sortieralgorithmus, plus zwei lineare Durchgänge am Ende und eine zusätzliche Schicht des Overheads der Zeiger-Indirektion.
Freut mich über Feedback zu diesem Ansatz. Hier ist meine vollständige Implementierung davon:
quelle
Ich weiß, dass dies viel beantwortet wurde. Ich wollte nur eine schnelle TS-Implementierung für alle veröffentlichen, die hier gelandet sind und danach suchen.
Die Methode wird nicht mehr direkt ausgeführt, wie dies bei der nativen Sortierung der Fall ist. Ich möchte auch darauf hinweisen, dass es nicht das effizienteste ist. Es werden zwei Schleifen der Ordnung O (n) hinzugefügt. Obwohl die Sortierung selbst höchstwahrscheinlich O (n log (n)) ist, ist sie geringer.
Einige der genannten Lösungen sind leistungsfähiger, obwohl dies möglicherweise weniger Code ist, auch wenn interner Code verwendet wird
Array.prototype.sort
.(Für eine Javascript-Lösung entfernen Sie einfach alle Typen.)
quelle
Nach dem DevBlog v8 und caniuse.com
Array.sort
ist bereits stabil wie in modernen Browsern von der Spezifikation erforderlich, so dass Sie nicht brauchen Ihre eigene Lösung zu rollen. Die einzige Ausnahme, die ich sehen kann, ist Edge, das bald auf Chrom umsteigen und es ebenfalls unterstützen sollte.quelle
quelle
Das Zählen der Sortierung ist schneller als das Zusammenführen der Sortierung (sie wird in O (n) -Zeit ausgeführt) und ist für die Verwendung mit ganzen Zahlen vorgesehen.
Beispiel:
quelle
array [3, 1, 3]
Hashes zu[undefined, 1, undefined, 3]
. Wir erhalten zwei nicht undefinierte Werte, während der Algorithmus drei davon erwartet.