Ich habe eine Reihe von Zeichenfolgen, die ich in JavaScript sortieren muss, jedoch ohne Berücksichtigung der Groß- und Kleinschreibung. Wie führe ich das durch?
javascript
sorting
case-insensitive
Jérôme Verstrynge
quelle
quelle
return a.localeCompare(b, 'en', {'sensitivity': 'base'});
toLowerCase()
wennlocaleCompare
dies in einigen Fällen bereits standardmäßig erfolgt. Weitereitems.sort(new Intl.Collator('en').compare)
für eine bessere Leistung zu verwenden. (Siehe MDN .)EDIT: Bitte beachten Sie, dass ich dies ursprünglich geschrieben habe, um die Technik zu veranschaulichen, anstatt die Leistung im Auge zu behalten. Eine kompaktere Lösung finden Sie auch in der Antwort @Ivan Krechetov.
quelle
toLowerCase
zweimal für jede Zeichenfolge aufgerufen werden. Es wäre effizienter, abgesenkte Versionen der Zeichenfolge in Variablen zu speichern..toLowerCase()
mehrmals für jedes Element im Array aufrufen . Zum Beispiel rufen 45 die Vergleichsfunktion auf, wenn 10 Elemente in umgekehrter Reihenfolge sortiert werden.var i = 0; ["z","y","x","w","v","u","t","s","r","q"].sort(function (a, b) {++i; return a.toLowerCase().localeCompare(b.toLowerCase());}); console.log("Calls to Compare: " + i); // i === 45
Es ist Zeit, diese alte Frage erneut zu prüfen.
Sie sollten keine Lösungen verwenden, auf die Sie sich verlassen können
toLowerCase
. Sie sind ineffizient und funktionieren in einigen Sprachen (z. B. Türkisch) einfach nicht . Bevorzugen Sie dies:Überprüfen Sie die Dokumentation auf Browserkompatibilität und alles, was Sie über die
sensitivity
Option wissen müssen .quelle
quelle
return a === b ? 0 : a > b ? 1 : -1;
["111", "33"]
, möchten wir möglicherweise, dass es zurückgegeben wird,["111", "33"]
da 1 in der Reihenfolge der Zeichencodes vor 3 steht. Die Funktion in dieser Antwort wird jedoch zurückgegeben,["33", "111"]
da die Nummer33
kleiner als die Nummer ist111
."33" > "111" === true
und33 > 111 === false
. Es funktioniert wie vorgesehen.Sie können auch das neue verwenden
Intl.Collator().compare
, das pro MDN beim Sortieren von Arrays effizienter ist . Der Nachteil ist, dass es von älteren Browsern nicht unterstützt wird. MDN gibt an, dass es in Safari überhaupt nicht unterstützt wird. Muss überprüft werden, da es besagt, dassIntl.Collator
unterstützt wird.quelle
Wenn Sie unabhängig von der Reihenfolge der Elemente im Eingabearray dieselbe Reihenfolge garantieren möchten, finden Sie hier eine stabile Sortierung:
quelle
Normalisieren Sie den Fall in der
.sort()
mit.toLowerCase()
.quelle
Sie können auch den Elvis-Operator verwenden:
Gibt:
Die localeCompare-Methode ist wahrscheinlich in Ordnung ...
Hinweis: Der Elvis-Operator ist eine Kurzform 'ternärer Operator', wenn sonst, normalerweise mit Zuweisung.
Wenn Sie das ?: Seitwärts betrachten, sieht es aus wie Elvis ...
dh anstelle von:
Sie können verwenden:
dh wenn y wahr ist, geben Sie 1 zurück (für die Zuordnung zu x), andernfalls geben Sie 2 zurück (für die Zuordnung zu x).
quelle
x = y ? y : z
können Sie dies tunx = y ?: z
. Javascript hat keinen tatsächlichen Elvis-Operator, aber Sie können ihnx = y || z
auf ähnliche Weise verwenden.Die anderen Antworten setzen voraus, dass das Array Zeichenfolgen enthält. Meine Methode ist besser, da sie auch dann funktioniert, wenn das Array null, undefinierte oder andere Nicht-Zeichenfolgen enthält.
Das
null
wird zwischen 'nulk' und 'nulm' sortiert. Aber dasundefined
wird immer zuletzt sortiert.quelle
(''+notdefined) === "undefined"
also würde es vor "z" sortierenArray.prototype.sort
: | nachschlagen sollen weil der Teil über(''+notdefined) === "undefined"
wirklich wahr ist ... was bedeutet, wenn Sie -1 und 1 in der Sortierfunktion umdrehen, um die Reihenfolge umzukehren, wird undefined immer noch bis zum Ende sortiert. Dies muss auch berücksichtigt werden, wenn die Vergleichsfunktion außerhalb des Kontexts einer Array-Sortierung verwendet wird (wie ich es war, als ich auf diese Frage stieß).Array.prototype.sort
Definition nachgedacht habe - noch ein paar Kommentare. Erstens muss das(''+a)
- ECMAScripttoString()
nicht für Elemente aufgerufen werden, bevor sie an compareFn übergeben werden. Zweitens ist die Tatsache , dassignoreCase
Erträge ,1
wenn (einschließlich der Gleich-but-für-Fall) Strings gleich Vergleich bedeutet die Spezifikation das Ergebnis nicht definieren , wenn es doppelte Werte sind (wahrscheinlich in Ordnung sein nur mit einigen unnötigen Swaps auftritt, glaube ich).undefined
ein Sonderfall ist, der für jedes x x <undefiniert und x> undefiniert beide falsch ist . Dasundefined
ist immer das Letzte, ist ein Nebenprodukt der Sortierimplementierung von sort. Ich habe versucht, das ('' + a) einfach in a zu ändern, aber es schlägt fehl. Ich versteheTypeError: a.toUpperCase is not a function
. OffenbartoString
wird nicht vor dem Aufruf von compareFn genannt.undefined
den Vergleich wird Fn nie genanntES6-Version:
["Foo", "bar"].sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }))
Quelle: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare
quelle
Zur Unterstützung der akzeptierten Antwort möchte ich hinzufügen, dass die folgende Funktion die Werte im zu sortierenden Original-Array so zu ändern scheint, dass nicht nur Kleinbuchstaben, sondern auch Großbuchstaben in Kleinbuchstaben sortiert werden. Dies ist ein Problem für mich, denn obwohl ich Mary neben Mary sehen möchte, möchte ich nicht, dass der Fall des ersten Wertes Mary in Kleinbuchstaben geändert wird.
In meinen Experimenten sortiert die folgende Funktion aus der akzeptierten Antwort korrekt, ändert jedoch die Werte nicht.
quelle
Dies kann hilfreich sein, wenn Sie Schwierigkeiten haben, Folgendes zu verstehen:
http://jsfiddle.net/ianjamieson/wmxn2ram/1/
quelle
Wenn wir in der obigen Funktion nur vergleichen, wenn Kleinbuchstaben zwei Werte a und b sind, haben wir nicht das hübsche Ergebnis.
Beispiel: Wenn das Array [A, a, B, b, c, C, D, d, e, E] ist und wir die obige Funktion verwenden, haben wir genau dieses Array. Es hat nichts geändert.
Um das Ergebnis [A, a, B, b, C, c, D, d, E, e] zu erhalten, sollten wir erneut vergleichen, wenn zwei Kleinbuchstaben gleich sind:
quelle
Ich habe die oberste Antwort in eine Polyfüllung gefüllt, damit ich .sortIgnoreCase () für String-Arrays aufrufen kann
quelle
Wickeln Sie Ihre Saiten ein
/ /i
. Dies ist eine einfache Möglichkeit, Regex zu verwenden, um das Gehäuse zu ignorierenquelle