Ich habe eine Reihe von JavaScript-Objekten:
var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
Wie kann ich sie nach dem Wert von last_nom
in JavaScript sortieren ?
Ich weiß Bescheid sort(a,b)
, aber das scheint nur bei Zeichenfolgen und Zahlen zu funktionieren. Muss ich toString()
meinen Objekten eine Methode hinzufügen ?
javascript
arrays
sorting
Tyrone Slothrop
quelle
quelle
Antworten:
Es ist einfach genug, eine eigene Vergleichsfunktion zu schreiben:
Oder inline (c / o Marco Demaio):
quelle
return a.last_nom.localeCompare(b.last_nom)
wird auch funktionieren.return a.value - b.value;
(ASC)localeCompare
ist wichtig, wenn Akzentzeichen in Fremdsprachen verwendet werden, und auch eleganter.Sie können auch eine dynamische Sortierfunktion erstellen, die Objekte nach ihrem übergebenen Wert sortiert:
Sie können also eine Reihe von Objekten wie folgt haben:
... und es wird funktionieren, wenn Sie:
Eigentlich beantwortet dies bereits die Frage. Der folgende Teil wurde geschrieben, weil viele Leute mich kontaktiert haben und sich beschwert haben, dass es nicht mit mehreren Parametern funktioniert .
Mehrere Parameter
Mit der folgenden Funktion können Sie Sortierfunktionen mit mehreren Sortierparametern generieren.
Was würde es Ihnen ermöglichen, so etwas zu tun:
Unterklassen-Array
Für die Glücklichen unter uns, die ES6 verwenden können, um die nativen Objekte zu erweitern:
Das würde dies ermöglichen:
quelle
dynamicSort()
im obigen Beispiel Großbuchstaben vor Kleinbuchstaben stehen. Wenn ich die Werte zum Beispiel habenAPd
,Aklin
undAbe
- die Ergebnisse in einer ASC sollte Art seinAbe
,Aklin
,APd
. Aber mit Ihrem Beispiel sind die ErgebnisseAPd
,Abe
,Aklin
. Wie auch immer, um dieses Verhalten zu korrigieren?var result = a[property].localeCompare(b[property]);
stattdessen anstelle von verwendenvar result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
.if( !isNaN(a[property]) ) a[property] = Number(a[property]); if( !isNaN(b[property]) ) b[property] = Number(b[property]);
In ES6 / ES2015 oder höher können Sie folgende Schritte ausführen:
Vor ES6 / ES2015
quelle
last_nom
nur die Nummer im Array zu verwenden :1
?objs.sort((a, b) => a.last_nom.localeCompare(b.last_nom, undefined, {numberic: true}));
underscore.js
Verwenden Sie Unterstrich, es ist klein und super ...
quelle
var sortedObjs = _.sortBy( objs, 'first_nom' );
.objs
wird dadurch nicht selbst sortiert. Die Funktion wird das Rück ein sortiertes Array. Das würde es expliziter machen.var reverseSortedObjs = _.sortBy( objs, 'first_nom' ).reverse();
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"> </script>
Lodash
für diejenigen, die dieses bevorzugenvar sortedObjs = _.sortBy( objs, 'first_nom' );
oder wenn Sie es in einer anderen Reihenfolge wollen:var sortedObjs = _.orderBy( objs, ['first_nom'],['dsc'] );
Verstehe nicht, warum die Leute es so kompliziert machen:
Für strengere Motoren:
Tauschen Sie den Operator aus, um ihn in umgekehrter alphabetischer Reihenfolge sortieren zu lassen.
quelle
if(a.count == b.count) return a.name > b.name; else return a.count > b.count;
Wenn Sie doppelte Nachnamen haben, können Sie diese nach Vornamen sortieren.
quelle
b
nach kommen solltea
in dem Array. Wenn eine positive Zahl zurückgegeben wird, bedeutet dies,a
dass danach kommen sollteb
. Wenn0
zurückgegeben wird, bedeutet dies, dass sie als gleich angesehen werden. Sie können immer die Dokumentation lesen: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…1, 0, -1
bevor ich dies hier gefragt habe. Ich habe einfach nicht die Informationen gefunden, die ich brauchte.Einfache und schnelle Lösung dieses Problems mithilfe der Vererbung von Prototypen:
Beispiel / Verwendung
Update: Ändert das ursprüngliche Array nicht mehr.
quelle
Ab 2018 gibt es eine viel kürzere und elegantere Lösung. Benutz einfach. Array.prototype.sort () .
Beispiel:
quelle
a.value - b.value
zum Vergleichen der Objektattribute ( in diesem Fall Zahlen ) verwendeten können für die verschiedenen Datenzeiten übernommen werden. Beispielsweise kann Regex verwendet werden, um jedes Paar der benachbarten Zeichenfolgen zu vergleichen .Alte Antwort, die nicht richtig ist:
AKTUALISIEREN
Aus Beauchamps Kommentar:
Besser lesbares Format:
Ohne verschachtelte Ternäre:
Erläuterung:
Number()
wirdtrue
zu1
undfalse
zu umgewandelt0
.quelle
arr.sort((a, b) => a.name < b.name ? -1 : (a.name > b.name ? 1 : 0))
Anstatt eine benutzerdefinierte Vergleichsfunktion zu verwenden, können Sie auch einen Objekttyp mit einer benutzerdefinierten
toString()
Methode erstellen (die von der Standardvergleichsfunktion aufgerufen wird):quelle
Lodash.js (Obermenge von Underscore.js )
Es ist gut, nicht für jede einfache Logik ein Framework hinzuzufügen, aber das Verlassen auf gut getestete Utility-Frameworks kann die Entwicklung beschleunigen und die Anzahl der Fehler reduzieren.
Lodash erzeugt sehr sauberen Code und fördert einen funktionaleren Programmierstil . Auf einen Blick wird klar, was die Absicht des Codes ist.
Das Problem von OP kann einfach gelöst werden als:
Mehr Info? ZB haben wir folgendes verschachteltes Objekt:
Wir können jetzt die Kurzform _.property verwenden
user.age
, um den Pfad zu der Eigenschaft anzugeben, die übereinstimmen soll. Wir werden die Benutzerobjekte nach der Eigenschaft des verschachtelten Alters sortieren. Ja, es ermöglicht die Zuordnung verschachtelter Eigenschaften!Willst du es umgekehrt? Kein Problem. Verwenden Sie _.reverse .
Möchten Sie beide mithilfe einer Kette kombinieren ?
Oder wann bevorzugen Sie den Fluss gegenüber der Kette?
quelle
Sie können verwenden
Einfachster Weg: Lodash
( https://lodash.com/docs/4.17.10#orderBy )
Diese Methode ähnelt _.sortBy, ermöglicht jedoch die Angabe der Sortierreihenfolge der Iterate, nach denen sortiert werden soll. Wenn die Reihenfolge nicht angegeben ist, werden alle Werte in aufsteigender Reihenfolge sortiert. Andernfalls geben Sie eine Reihenfolge von "desc" für absteigend oder "asc" für aufsteigende Sortierreihenfolge der entsprechenden Werte an.
Argumente
Sammlung (Array | Objekt): Die Sammlung, über die iteriert werden soll. [iteratees = [_. identity]] (Array [] | Function [] | Object [] | string []): Die zu sortierenden Iteratees. [orders] (string []): Die Sortierreihenfolge von Iteraten.
Kehrt zurück
(Array): Gibt das neue sortierte Array zurück.
quelle
Hier gibt es viele gute Antworten, aber ich möchte darauf hinweisen, dass sie sehr einfach erweitert werden können, um eine viel komplexere Sortierung zu erreichen. Das einzige, was Sie tun müssen, ist, den Operator OR zu verwenden, um Vergleichsfunktionen wie folgt zu verketten:
Wo
fn1
,fn2
... sind die Sortierfunktionen der Rückkehr [-1,0,1]. Dies führt zu "Sortieren nach fn1", "Sortieren nach fn2", was in SQL ziemlich gleich ORDER BY ist.Diese Lösung basiert auf dem Verhalten des
||
Operators, der den ersten ausgewerteten Ausdruck auswertet, der in true konvertiert werden kann .Die einfachste Form hat nur eine Inline-Funktion wie diese:
Mit zwei Schritten mit
last_nom
,first_nom
Sortierreihenfolge würde wie folgt aussehen:Eine generische Vergleichsfunktion könnte ungefähr so aussehen:
Diese Funktion kann erweitert werden, um numerische Felder, Groß- / Kleinschreibung, willkürliche Datentypen usw. zu unterstützen.
Sie können sie verwenden, um sie nach Sortierpriorität zu verketten:
Der Punkt hier ist, dass reines JavaScript mit funktionalem Ansatz Sie ohne externe Bibliotheken oder komplexen Code weit bringen kann. Es ist auch sehr effektiv, da kein String-Parsing durchgeführt werden muss
quelle
Anwendungsbeispiel:
Skript:
quelle
1, 0, -1
für die Sortierreihenfolge verwendet werden. Selbst mit Ihrer obigen Erklärung, die sehr gut aussieht - ich verstehe sie immer noch nicht ganz. Ich denke immer an die-1
Verwendung der Array-Längeneigenschaft, dh:arr.length = -1
bedeutet, dass das Element nicht gefunden wird. Ich vermische hier wahrscheinlich die Dinge, aber können Sie mir helfen zu verstehen, warum Ziffern1, 0, -1
zur Bestimmung der Reihenfolge verwendet werden? Vielen Dank.a
undb
, wenna
größer alsb
1, fügen Sie 1 zum Index von hinzua
und platzieren Sie es dahinterb
, wenna
kleiner alsb
, subtrahiere 1 vona
und lege es vorb
. Wenna
und gleichb
sind, fügen Sie 0 hinzua
und lassen Sie es dort, wo es ist.Ich habe diesen speziellen Ansatz nicht vorgeschlagen, daher hier eine knappe Vergleichsmethode, die ich gerne verwende und die für beide funktioniert
string
undnumber
:Hier ist eine Erklärung von
sortBy()
:sortBy()
akzeptiert afn
, das auswählt, welcher Wert aus einem Objekt als Vergleich verwendet werden soll, und gibt eine Funktion zurück, an die direkt übergeben werden kannArray.prototype.sort()
. In diesem Beispiel verwenden wiro.last_nom
als Vergleichswert, also immer dann, wenn wir zwei Objekte überArray.prototype.sort()
zund
wir gebrauchen
um sie zu vergleichen.
Daran erinnern
fn = o => o.last_nom
wir uns können wir die Vergleichsfunktion auf das Äquivalent erweiternDas logische ODER
||
Operator verfügt über eine Kurzschlussfunktion, die hier sehr nützlich ist. Aufgrund seiner Funktionsweise bedeutet der Hauptteil der obigen FunktionAls zusätzlichen Bonus ist hier das Äquivalent in ECMAScript 5 ohne Pfeilfunktionen, das leider ausführlicher ist:
quelle
Ich weiß, dass diese Frage zu alt ist, aber ich habe keine ähnliche Implementierung wie meine gesehen.
Diese Version basiert auf der Schwartzschen Transformationssprache .
Hier ist ein Beispiel für die Verwendung:
quelle
Sortieren (mehr) komplexer Arrays von Objekten
Da Sie wahrscheinlich auf komplexere Datenstrukturen wie dieses Array stoßen, würde ich die Lösung erweitern.
TL; DR
Problem
Ich bin auf das Folgende gestoßen und konnte es nicht ändern. Ich wollte das Objekt auch nicht vorübergehend abflachen. Ich wollte auch keinen Unterstrich / lodash verwenden, hauptsächlich aus Leistungsgründen und um Spaß daran zu haben, es selbst zu implementieren.
Tor
Das Ziel ist es, es primär nach
People.Name.name
und sekundär nach zu sortierenPeople.Name.surname
Hindernisse
In der Basislösung wird nun die Klammernotation verwendet, um die Eigenschaften zu berechnen, nach denen dynamisch sortiert werden soll. Hier müssten wir jedoch die Klammer-Notation auch dynamisch konstruieren, da Sie einige davon erwarten würden
People['Name.name']
davon funktionieren würden - was nicht funktioniert.Das einfache Tun
People['Name']['name']
ist dagegen statisch und erlaubt Ihnen nur, das n hinunterzugehen te Ebene .Lösung
Der Hauptzusatz besteht darin, den Objektbaum entlangzugehen und den Wert des letzten Blattes, das Sie angeben müssen, sowie eines Zwischenblatts zu bestimmen.
Beispiel
Arbeitsbeispiel für JSBin
quelle
Noch eine Option:
sortiert standardmäßig aufsteigend.
quelle
Eine einfache Funktion, die ein Objektarray nach einer Eigenschaft sortiert
Verwendungszweck:
quelle
Ein einfacher Weg:
'.toLowerCase()'
Beachten Sie, dass dies erforderlich ist, um Fehler beim Vergleichen von Zeichenfolgen zu vermeiden.quelle
objs.sort( (a,b) => b.last_nom.toLowerCase() < a.last_nom.toLowerCase() );
zusätzliche Desc-Parameter für Ege Özcan- Code
quelle
Wenn Sie die dynamische Lösung von Ege mit der Idee von Vinay kombinieren, erhalten Sie eine schöne robuste Lösung:
Verwendungszweck:
quelle
Gemäß Ihrem Beispiel müssen Sie nach zwei Feldern (Nachname, Vorname) und nicht nach einem Feld sortieren. Sie können die Alasql- Bibliothek verwenden, um diese Sortierung in einer Zeile vorzunehmen:
Versuchen Sie dieses Beispiel bei jsFiddle .
quelle
quelle
Angesichts des ursprünglichen Beispiels:
Nach mehreren Feldern sortieren:
Anmerkungen
a.localeCompare(b)
wird allgemein unterstützt und kehrt -1,0,1 wenna<b
,a==b
,a>b
bzw..||
in der letzten Zeile gibtlast_nom
Vorrang vorfirst_nom
.var age_order = left.age - right.age;
return -last_nom_order || -first_nom_order || -age_order;
quelle
Versuche dies,
quelle
Möglicherweise müssen Sie sie in Kleinbuchstaben umwandeln, um Verwirrung zu vermeiden.
quelle
quelle
Mit Ramda,
npm install ramda
quelle
Dies ist ein einfaches Problem, ich weiß nicht, warum Menschen so komplexe Lösungen haben.
Eine einfache Sortierfunktion (basierend auf dem Schnellsortieralgorithmus ):
Anwendungsbeispiel:
quelle