Ich versuche, ein Array mit Objekten basierend auf mehreren Attributen zu sortieren. Das heißt, wenn das erste Attribut zwischen zwei Objekten gleich ist, sollte ein zweites Attribut verwendet werden, um die beiden Objekte zu kombinieren. Betrachten Sie beispielsweise das folgende Array:
var patients = [
[{name: 'John', roomNumber: 1, bedNumber: 1}],
[{name: 'Lisa', roomNumber: 1, bedNumber: 2}],
[{name: 'Chris', roomNumber: 2, bedNumber: 1}],
[{name: 'Omar', roomNumber: 3, bedNumber: 1}]
];
Wenn roomNumber
ich diese nach dem Attribut sortiere, würde ich den folgenden Code verwenden:
var sortedArray = _.sortBy(patients, function(patient) {
return patient[0].roomNumber;
});
Das funktioniert gut, aber wie gehe ich vor, damit 'John' und 'Lisa' richtig sortiert werden?
quelle
[0]
Indexer ist erforderlich, da es sich im ursprünglichen Beispielpatients
um ein Array von Arrays handelt. Dies ist auch der Grund, warum die "einfachere Lösung" in dem in einem anderen Kommentar erwähnten Blog-Beitrag hier nicht funktioniert.Hier ist ein hackiger Trick, den ich manchmal in diesen Fällen verwende: Kombinieren Sie die Eigenschaften so, dass das Ergebnis sortierbar ist:
Wie gesagt, das ist ziemlich hackig. Um dies richtig zu machen, möchten Sie wahrscheinlich die JavaScript-
sort
Kernmethode verwenden :Natürlich dies wird Ihr Array an Ort und Stelle sortieren. Wenn Sie eine sortierte Kopie wünschen (wie
_.sortBy
Sie es gerne hätten), klonen Sie zuerst das Array:Aus Langeweile habe ich auch hier eine allgemeine Lösung geschrieben (um nach einer beliebigen Anzahl von Schlüsseln zu sortieren): Schauen Sie mal rein .
quelle
return [patient[0].roomNumber, patient[0].name];
ohne das nicht genugjoin
?compare
Handle Werte, die nicht primitive Werte -undefined
,null
oder einfache Objekte?Ich weiß, dass ich zu spät zur Party komme, aber ich wollte dies für diejenigen hinzufügen, die eine sauberere und schnellere Lösung benötigen, als die bereits vorgeschlagenen. Sie können sortBy-Aufrufe in der Reihenfolge der am wenigsten wichtigen Eigenschaft mit der wichtigsten Eigenschaft verketten. Im folgenden Code erstelle ich ein neues Array von Patienten, sortiert nach Name in RoomNumber, aus dem ursprünglichen Array namens Patienten .
quelle
Übrigens ist Ihr Initialisierer für Patienten ein bisschen komisch, nicht wahr? Warum initialisieren Sie diese Variable nicht als solche - als echtes Array von Objekten - Sie können dies mit _.flatten () tun und nicht als Array von Arrays einzelner Objekte, möglicherweise ist es ein Tippfehler):
Ich sortierte die Liste anders und fügte Kiko in Lisas Bett hinzu. Nur zum Spaß und sehen, welche Änderungen vorgenommen werden ...
inspizieren sortiert und Sie werden dies sehen
Meine Antwort lautet also: Verwenden Sie ein Array in Ihrer Rückruffunktion. Dies ist der Antwort von Dan Tao ziemlich ähnlich. Ich vergesse nur den Join (möglicherweise, weil ich das Array von Arrays mit einem eindeutigen Element entfernt habe :)).
Verwenden Sie dann Ihre Datenstruktur wäre :
und eine Testladung wäre interessant ...
quelle
Keine dieser Antworten ist ideal als Allzweckmethode für die Verwendung mehrerer Felder in einer Sortierung. Alle oben genannten Ansätze sind ineffizient, da sie entweder das Sortieren des Arrays mehrmals erfordern (was auf einer ausreichend großen Liste die Dinge erheblich verlangsamen kann) oder große Mengen an Müllobjekten generieren, die die VM bereinigen (und letztendlich verlangsamen muss) das Programm runter).
Hier ist eine Lösung, die schnell und effizient ist, eine einfache umgekehrte Sortierung ermöglicht und mit
underscore
oderlodash
oder direkt mit verwendet werden kannArray.sort
Der wichtigste Teil ist die
compositeComparator
Methode, die ein Array von Komparatorfunktionen verwendet und eine neue zusammengesetzte Komparatorfunktion zurückgibt.Sie benötigen außerdem eine Komparatorfunktion, um die Felder zu vergleichen, nach denen Sie sortieren möchten. Die
naturalSort
Funktion erstellt einen Komparator für ein bestimmtes Feld. Das Schreiben eines Komparators für die umgekehrte Sortierung ist ebenfalls trivial.(Der gesamte bisherige Code ist wiederverwendbar und kann beispielsweise im Dienstprogrammmodul gespeichert werden.)
Als Nächstes müssen Sie den zusammengesetzten Komparator erstellen. In unserem Beispiel würde es so aussehen:
Dies wird nach Raumnummer sortiert, gefolgt von Name. Das Hinzufügen zusätzlicher Sortierkriterien ist trivial und hat keinen Einfluss auf die Leistung der Sortierung.
Gibt Folgendes zurück
Der Grund, warum ich diese Methode bevorzuge, ist, dass sie eine schnelle Sortierung nach einer beliebigen Anzahl von Feldern ermöglicht, nicht viel Müll erzeugt oder eine Zeichenfolgenverkettung innerhalb der Sortierung durchführt und einfach verwendet werden kann, sodass einige Spalten umgekehrt sortiert werden, während Auftragsspalten natürlich verwendet werden Sortieren.
quelle
Einfaches Beispiel von http://janetriley.net/2014/12/sort-on-multiple-keys-with-underscores-sortby.html (mit freundlicher Genehmigung von @MikeDevenney)
Code
Mit Ihren Daten
quelle
Vielleicht unterscheiden sich underscore.js oder nur Javascript-Engines jetzt von denen, als diese Antworten geschrieben wurden, aber ich konnte dies lösen, indem ich nur ein Array der Sortierschlüssel zurückgab.
In Aktion sehen Sie bitte diese Geige: https://jsfiddle.net/mikeular/xenu3u91/
quelle
Nur ein Array von Eigenschaften , mit denen Sie sortieren möchten:
ES6-Syntax
ES5-Syntax
Dies hat keine Nebenwirkungen beim Konvertieren einer Zahl in eine Zeichenfolge.
quelle
Sie können die Eigenschaften, nach denen Sie sortieren möchten, im Iterator verketten:
oder etwas Äquivalentes.
HINWEIS: Da Sie das numerische Attribut roomNumber in eine Zeichenfolge konvertieren, müssten Sie etwas tun, wenn Sie Raumnummern> 10 hätten. Andernfalls wird 11 vor 2 stehen. Sie können mit führenden Nullen auffüllen, um das Problem zu lösen, dh 01 anstelle von 01 1.
quelle
Ich denke, Sie sollten besser verwenden
_.orderBy
alssortBy
:quelle
_.orderBy
funktioniert, aber es ist eine Methode der lodash-Bibliothek, kein Unterstrich: lodash.com/docs/4.17.4#orderBy lodash ist meistens ein Ersatz für Unterstriche, daher ist es möglicherweise für das OP geeignet.Wenn Sie Angular verwenden, können Sie den Nummernfilter in der HTML-Datei verwenden, anstatt JS- oder CSS-Handler hinzuzufügen. Beispielsweise:
In diesem Beispiel wird val = 1234567 als angezeigt
Beispiel und weitere Anleitung unter: https://docs.angularjs.org/api/ng/filter/number
quelle