Vorrei ordinare una serie di stringhe (in javascript) in modo che i gruppi di cifre all'interno delle stringhe vengano confrontati come numeri interi e non come stringhe. Non sono preoccupato per i numeri firmati o in virgola mobile.come ordinare le stringhe in javascript numericamente
per esempio, il risultato dovrebbe essere ["a1b3","a9b2","a10b2","a10b11"]
non ["a1b3","a10b11","a10b2","a9b2"]
Il modo più semplice per farlo sembra essere suddividendo ciascuna stringa su confini intorno gruppi di cifre. C'è un pattern che posso passare a String.split per dividere i limiti dei caratteri senza rimuovere alcun carattere?
"abc11def22ghi".split(/?/) = ["abc","11","def","22","ghi"];
O c'è un altro modo per confrontare le stringhe che non comporta dividendoli, forse da imbottitura tutti i gruppi di cifre con zeri iniziali in modo che siano della stessa lunghezza?
"aa1bb" => "aa00000001bb", "aa10bb" => "aa00000010bb"
Sto lavorando con stringhe arbitrarie, non stringhe che hanno un accordo specifico di gruppi di cifre.
Edit:
Mi piace il /(\d+)/
uno di linea da Gaby per dividere l'array. Quanto è retrocompatibile?
Le soluzioni che analizzano le stringhe in un modo che può essere utilizzato per ricostruire gli originali sono molto più efficienti di questa funzione di confronto. Nessuna delle risposte gestisce alcune stringhe che iniziano con cifre e altre no, ma ciò sarebbe abbastanza facile da porre rimedio e non era esplicito nella domanda originale.
["a100","a20","a3","a3b","a3b100","a3b20","a3b3","!!","~~","9","10","9.5"].sort(function (inA , inB) {
var result = 0;
var a , b , pattern = /(\d+)/;
var as = inA.split(pattern);
var bs = inB.split(pattern);
var index , count = as.length;
if (('' === as[0]) === ('' === bs[0])) {
if (count > bs.length) count = bs.length;
for (index = 0 ; index < count && 0 === result ; ++index) {
a = as[index]; b = bs[index];
if (index & 1) {
result = a - b;
} else {
result = !(a < b) ? (a > b) ? 1 : 0 : -1;
}
}
if (0 === result) result = as.length - bs.length;
} else {
result = !(inA < inB) ? (inA > inB) ? 1 : 0 : -1;
}
return result;
}).toString();
risultato: "!!,9,9.5,10,a3,a3b,a3b3,a3b20,a3b100,a20,a100,~~"
Le parti non numeriche sono sempre le stesse? In caso contrario, l'algoritmo di ordinamento dovrebbe ordinarli in ordine ASCII? –
Nel tuo esempio, stai estraendo 13, 92, 102, 1011? O è più simile a 1.3, 9.2, 10.2, 10.11? Voglio dire, il primo numero è più significativo o le lettere sono semplicemente ignorate? –
... oh, vuoi ancora ordinare i non interi anche io, lo capisco adesso ... –