Me gustaría ordenar una matriz de cadenas (en javascript) de modo que los grupos de dígitos dentro de las cadenas se comparen como enteros y no como cadenas. No me preocupan los números con signo o coma flotante.cómo ordenar cadenas en javascript numéricamente
por ejemplo, el resultado debería ser ["a1b3","a9b2","a10b2","a10b11"]
no ["a1b3","a10b11","a10b2","a9b2"]
La forma más sencilla de hacer esto parece ser la división de cada cadena de límites en torno a grupos de dígitos. ¿Hay algún patrón que pueda pasar a String.split para dividir los límites del personaje sin quitar ningún carácter?
"abc11def22ghi".split(/?/) = ["abc","11","def","22","ghi"];
O hay otra forma de comparar cadenas que no esté relacionado con dividirlos, tal vez mediante el relleno de todos los grupos de dígitos con ceros a la izquierda por lo que son de la misma longitud?
"aa1bb" => "aa00000001bb", "aa10bb" => "aa00000010bb"
estoy trabajando con cadenas arbitrarias, no cadenas que tienen una disposición específica de grupos de dígitos.
Editar:
me gusta la /(\d+)/
un trazador de líneas de Gaby para dividir la matriz. ¿Qué tan compatible con versiones anteriores es eso?
Las soluciones que analizan las cadenas de una manera que se puede utilizar para reconstruir los originales son mucho más eficientes que esta función de comparación. Ninguna de las respuestas maneja algunas cadenas que comienzan con dígitos y otras no, pero eso sería bastante fácil de solucionar y no fue explícito en la pregunta original.
["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();
resultado: "!!,9,9.5,10,a3,a3b,a3b3,a3b20,a3b100,a20,a100,~~"
¿Las partes no numéricas son siempre las mismas? De lo contrario, ¿debería el algoritmo de clasificación ordenarlos en orden ASCII? –
En su ejemplo, están extrayendo 13, 92, 102, 1011? ¿O es más como 1.3, 9.2, 10.2, 10.11? Quiero decir, ¿es el primer número más significativo o las letras simplemente se ignoran? –
... oh, todavía quieres ordenar los no enteros, lo entiendo ahora ... –