Natürliche Art von alphanumerischen Zeichenfolgen in JavaScript
Lesezeit: 7 Minuten
ptrn
Ich suche nach der einfachsten Möglichkeit, ein Array zu sortieren, das aus Zahlen und Text und einer Kombination davon besteht.
Z.B,
'123asd'
'19asd'
'12345asd'
'asd123'
'asd12'
verwandelt sich in
'19asd'
'123asd'
'12345asd'
'asd12'
'asd123'
Dies wird in Kombination mit der Lösung einer anderen Frage verwendet, die ich hier gestellt habe.
Die Sortierfunktion an sich funktioniert, was ich brauche, ist eine Funktion, die sagen kann, dass ’19asd’ kleiner als ‘123asd’ ist.
Ich schreibe dies in JavaScript.
Ich suche eine Funktion zur natürlichen Sortierung.
siehe auch How do you do string comparison in JavaScript? auf stackoverflow.com/questions/51165/…
– Adriano
26. September 2014 um 12:19 Uhr
Die ursprüngliche Frage wurde 2010 gestellt, also wäre es nicht überraschend 🙂
– ptrn
23. Juli 2015 um 21:32 Uhr
Mögliches Duplikat von How to sort strings in JavaScript
– Feeela
28. August 2018 um 11:35 Uhr
@feeela Das ist keine natürliche Sorte
– Bergi
13. Januar 2022 um 9:01 Uhr
frodo2975
Dies ist jetzt in modernen Browsern möglich GebietsschemaVergleichen. Durch das Passieren der numeric: true Option, erkennt es Zahlen intelligent. Sie können Groß- und Kleinschreibung beachten sensitivity: 'base'. Es wurde in Chrome, Firefox und getestet InternetExplorer 11.
Hier ist ein Beispiel. Es kehrt zurück 1was bedeutet, dass 10 nach 2 kommt:
Für die Leistung beim Sortieren einer großen Anzahl von Zeichenfolgen der Artikel sagt:
Beim Vergleichen einer großen Anzahl von Zeichenfolgen, wie z. B. beim Sortieren großer Arrays, ist es besser, ein Intl.Collator-Objekt zu erstellen und die von seiner Vergleichseigenschaft bereitgestellte Funktion zu verwenden.
var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
var myArray = ['1_Document', '11_Document', '2_Document'];
console.log(myArray.sort(collator.compare));
Um den obigen Kommentar zu verdeutlichen: „Wenn das locales-Argument nicht angegeben oder nicht definiert ist, wird das Standardgebietsschema der Laufzeitumgebung verwendet.“
– gkiely
28. Juli 2019 um 1:28 Uhr
@frodo2975 Hier, was ist hier ein undefinierter Parameter … was ist der Zweck?
– Jayden
28. Februar 2022 um 6:15 Uhr
@Jayden Wir übergeben undefined, um zu vermeiden, dass ein Gebietsschema angegeben werden muss. Es wird das Standardgebietsschema des Browsers verwendet.
– frodo2975
2. März 2022 um 20:32 Uhr
D0rm1nd0
Wenn Sie ein Array von Objekten haben, können Sie es so machen:
Aber um das Sortieren eines Arrays zu beschleunigen, manipulieren Sie das Array vor dem Sortieren, sodass Sie Kleinbuchstaben und den regulären Ausdruck nur einmal konvertieren müssen, anstatt in jedem Schritt durch die Sortierung.
Würde das in meinem Fall funktionieren, wenn das innere Array die Reihenfolge des äußeren bestimmt?
– ptrn
10. Mai 2010 um 13:11 Uhr
Was ist String.prototype.tlc()? Ist das dein eigener Code oder hast du den irgendwo her? Wenn letzteres der Fall ist, verlinken Sie bitte auf die Seite.
– Andi E
10. Mai 2010 um 13:15 Uhr
Entschuldigung für den Fehler – korrigiert, danke. Wenn Sie möchten[1] und B[1] Um die Sortierung zu steuern, verwenden Sie a= String(a[1]).toLowerCase(); b= Zeichenkette(b[1]).toLowerCase();
– kennebec
10. Mai 2010 um 13:17 Uhr
Ich hatte gerade eine Liste mit Daten, die ich sortieren wollte, dachte, es sollte in der Chrome Dev Tools-Konsole einfach sein – danke für die Funktion!
– ajh158
12. April 2013 um 12:30 Uhr
Stefan Quan
Stellen Sie sich eine Nummer-Null-Padding-Funktion vor n => n.padStart(8, "0") das nimmt eine beliebige Zahl und füllt sie auf, dh
“19” -> “00000019”
“123” -> “00000123”
Diese Funktion kann verwendet werden, um beim Sortieren zu helfen "19" Zeichenfolge, sodass sie vor der angezeigt wird "123" Schnur.
Lassen Sie uns eine Regex hinzufügen /\d+/g Erstellen der natürlichen Expansionsfunktion str => str.replace(/\d+/g, n => n.padStart(8, "0")) die nur Zahlenabschnitte in einer Zeichenfolge findet und sie auffüllt, dh
“19asd” -> “00000019asd”
“123asd” -> “00000123asd”
Jetzt können wir diese natürliche Erweiterungsfunktion verwenden, um die Sortierung nach natürlicher Reihenfolge zu implementieren:
const list = [
"123asd",
"19asd",
"12345asd",
"asd123",
"asd12"
];
const ne = str => str.replace(/\d+/g, n => n.padStart(8, "0"));
const nc = (a,b) => ne(a).localeCompare(ne(b));
console.log(list.map(ne).sort()); // intermediate values
console.log(list.sort(nc)); // result
Die Zwischenergebnisse demonstriert durch list.map(ne).sort() zeigen was die ne natürliche Expansionsfunktion tut. Es implementiert das Auffüllen von Zahlen mit Nullen nur für die Zahlenteile der Zeichenfolge und lässt die Alphabetkomponenten unverändert.
Die endgültige Version der Lösung implementiert einen natürlichen Ordnungskomparator nc umgesetzt als (a,b) => ne(a).localeCompare(ne(b)) und verwendet es in list.sort(nc) damit die Dinge richtig geordnet werden:
Es akzeptiert nicht nur Arrays von Strings, sondern kann auch nach dem Wert eines bestimmten Schlüssels in einem Array von Objekten sortieren. Es kann auch Zeichenfolgen von Währungen, Datumsangaben, Währungen und einer Reihe anderer Dinge automatisch identifizieren und sortieren.
Überraschenderweise sind es auch nur 1,6 kB, wenn es gezippt ist.
Obwohl nicht ausdrücklich angegeben, scheint Ihre Antwort spezifisch für Node.JS zu sein.
– Stephen Quan
24. August 2021 um 22:20 Uhr
@StephenQuan Danke – Ich aktualisiere die Antwort, um die ES6-Modulsyntax zu verwenden, die weniger NodeJS-spezifisch ist.
– Julian
30. August 2021 um 23:23 Uhr
Peter Mortensen
Aufbauend auf kennebecs Antwort und mit dem Code that Brian Huismann & David Kölle erstellt, hier ist eine modifizierte Prototyp-Sortierung für ein Array von Objekten:
//Usage: unsortedArrayOfObjects.alphaNumObjectSort("name");
//Test Case: var unsortedArrayOfObjects = [{name: "a1"}, {name: "a2"}, {name: "a3"}, {name: "a10"}, {name: "a5"}, {name: "a13"}, {name: "a20"}, {name: "a8"}, {name: "8b7uaf5q11"}];
//Sorted: [{name: "8b7uaf5q11"}, {name: "a1"}, {name: "a2"}, {name: "a3"}, {name: "a5"}, {name: "a8"}, {name: "a10"}, {name: "a13"}, {name: "a20"}]
// **Sorts in place**
Array.prototype.alphaNumObjectSort = function(attribute, caseInsensitive) {
for (var z = 0, t; t = this[z]; z++) {
this[z].sortArray = new Array();
var x = 0, y = -1, n = 0, i, j;
while (i = (j = t[attribute].charAt(x++)).charCodeAt(0)) {
var m = (i == 46 || (i >=48 && i <= 57));
if (m !== n) {
this[z].sortArray[++y] = "";
n = m;
}
this[z].sortArray[y] += j;
}
}
this.sort(function(a, b) {
for (var x = 0, aa, bb; (aa = a.sortArray[x]) && (bb = b.sortArray[x]); x++) {
if (caseInsensitive) {
aa = aa.toLowerCase();
bb = bb.toLowerCase();
}
if (aa !== bb) {
var c = Number(aa), d = Number(bb);
if (c == aa && d == bb) {
return c - d;
} else {
return (aa > bb) ? 1 : -1;
}
}
}
return a.sortArray.length - b.sortArray.length;
});
for (var z = 0; z < this.length; z++) {
// Here we're deleting the unused "sortArray" instead of joining the string parts
delete this[z]["sortArray"];
}
}
Obwohl nicht ausdrücklich angegeben, scheint Ihre Antwort spezifisch für Node.JS zu sein.
– Stephen Quan
24. August 2021 um 22:20 Uhr
@StephenQuan Danke – Ich aktualisiere die Antwort, um die ES6-Modulsyntax zu verwenden, die weniger NodeJS-spezifisch ist.
– Julian
30. August 2021 um 23:23 Uhr
14422800cookie-checkNatürliche Art von alphanumerischen Zeichenfolgen in JavaScriptyes
siehe auch
How do you do string comparison in JavaScript?
auf stackoverflow.com/questions/51165/…– Adriano
26. September 2014 um 12:19 Uhr
Die ursprüngliche Frage wurde 2010 gestellt, also wäre es nicht überraschend 🙂
– ptrn
23. Juli 2015 um 21:32 Uhr
Mögliches Duplikat von How to sort strings in JavaScript
– Feeela
28. August 2018 um 11:35 Uhr
@feeela Das ist keine natürliche Sorte
– Bergi
13. Januar 2022 um 9:01 Uhr