Je voudrais trier un tableau de chaînes (en javascript) de sorte que les groupes de chiffres dans les chaînes soient comparés comme des entiers et non comme des chaînes. Je ne suis pas inquiet pour les nombres à virgule flottante ou signée.comment trier les chaînes en javascript numériquement
par exemple, le résultat devrait être ["a1b3","a9b2","a10b2","a10b11"]
pas ["a1b3","a10b11","a10b2","a9b2"]
La meilleure façon de faire semble être diviser chaque chaîne sur les limites autour des groupes de chiffres. Y a-t-il un motif que je peux transmettre à String.split pour séparer les limites de caractères sans enlever aucun caractère?
"abc11def22ghi".split(/?/) = ["abc","11","def","22","ghi"];
Ou est-il une autre façon de comparer les chaînes qui ne concernent pas les diviser, peut-être par padding tous les groupes de chiffres avec des zéros de sorte qu'ils sont de la même longueur?
"aa1bb" => "aa00000001bb", "aa10bb" => "aa00000010bb"
Je travaille avec des chaînes arbitraires, et non des chaînes qui ont une disposition particulière des groupes de chiffres.
Edit:
J'aime le /(\d+)/
une doublure de Gaby pour diviser la matrice. Comment rétrocompatible est-ce?
Les solutions qui analysent les chaînes une fois d'une manière qui peut être utilisée pour reconstruire les originaux sont beaucoup plus efficaces que cette fonction de comparaison. Aucune des réponses ne gère certaines chaînes commençant par des chiffres et d'autres non, mais cela serait assez facile à corriger et n'était pas explicite dans la question initiale.
["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();
Résultat: "!!,9,9.5,10,a3,a3b,a3b3,a3b20,a3b100,a20,a100,~~"
Les parties non numériques sont-elles toujours les mêmes? Si non, l'algorithme de tri doit-il les trier dans l'ordre ASCII? –
Dans votre exemple, extrayez-vous 13, 92, 102, 1011? Ou est-ce plus comme 1.3, 9.2, 10.2, 10.11? Je veux dire est le premier nombre plus significatif ou les lettres sont-elles simplement ignorées? –
... oh vous voulez toujours trier sur les non-entiers aussi, je l'obtiens maintenant ... –