une - type de variable javascript
Javascript: sorte naturelle de chaînes alphanumériques (4)
Je suis à la recherche de la façon la plus simple de trier un tableau constitué de chiffres et de texte, et une combinaison de ceux-ci.
Par exemple
'123asd'
'19asd'
'12345asd'
'asd123'
'asd12'
se transforme en
'19asd'
'123asd'
'12345asd'
'asd12'
'asd123'
Cela va être utilisé en combinaison avec la solution à une autre question que j'ai posée ici .
La fonction de tri fonctionne en soi, ce dont j'ai besoin est une fonction qui peut dire que '19asd' est plus petit que '123asd'.
J'écris ceci en JavaScript.
Edit: comme l' a souligné adormitu , ce que je recherche est une fonction de tri naturel
Ceci est maintenant possible dans les navigateurs modernes en utilisant localeCompare. En passant l'option numeric: true
, il reconnaîtra intelligemment les nombres. Vous pouvez faire une distinction entre la casse et la sensitivity: 'base'
. Testé dans Chrome, Firefox et IE11.
Voici un exemple. Il renvoie 1
, ce qui signifie 10 va après 2:
'10'.localeCompare('2', undefined, {numeric: true, sensitivity: 'base'})
Pour les performances lors du tri d'un grand nombre de chaînes, l'article dit:
Lorsque vous comparez un grand nombre de chaînes, par exemple pour trier de grands tableaux, il est préférable de créer un objet Intl.Collator et d'utiliser la fonction fournie par sa propriété compare. Lien Docs
var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
var myArray = ['1_Document', '11_Document', '2_Document'];
console.log(myArray.sort(collator.compare));
Donc vous avez besoin d'un tri naturel ?
Si oui, peut - être que ce script de Brian Huisman basé sur le travail de David Koëlle serait ce dont vous avez besoin.
Il semble que la solution de Brian Huisman soit maintenant directement hébergée sur le blog de David Koelle:
Imaginez une fonction de remplissage à 8 chiffres qui transforme:
- '123asd' -> '00000123asd'
- '19asd' -> '00000019asd'
Nous pouvons utiliser les chaînes rembourrées pour nous aider à trier '19asd' avant '123asd'.
Utilisez l'expression régulière /\d+/g
pour trouver tous les nombres qui doivent être complétés:
str.replace(/\d+/g, pad)
Ce qui suit démontre le tri en utilisant cette technique:
var list = [
'123asd',
'19asd',
'12345asd',
'asd123',
'asd12'
];
function pad(n) { return ("00000000" + n).substr(-8); }
function natural_expand(a) { return a.replace(/\d+/g, pad) };
function natural_compare(a, b) {
return natural_expand(a).localeCompare(natural_expand(b));
}
console.log(list.map(natural_expand).sort()); // intermediate values
console.log(list.sort(natural_compare)); // result
Les résultats intermédiaires montrent ce que fait la routine natural_expand () et vous permettent de comprendre comment fonctionnera la routine naturelle_compare suivante:
[
"00000019asd",
"00000123asd",
"00012345asd",
"asd00000012",
"asd00000123"
]
Les sorties:
[
"19asd",
"123asd",
"12345asd",
"asd12",
"asd123"
]
Pour comparer les valeurs, vous pouvez utiliser une méthode de comparaison
function naturalSorter(as, bs){
var a, b, a1, b1, i= 0, n, L,
rx=/(\.\d+)|(\d+(\.\d+)?)|([^\d.]+)|(\.\D+)|(\.$)/g;
if(as=== bs) return 0;
a= as.toLowerCase().match(rx);
b= bs.toLowerCase().match(rx);
L= a.length;
while(i<L){
if(!b[i]) return 1;
a1= a[i],
b1= b[i++];
if(a1!== b1){
n= a1-b1;
if(!isNaN(n)) return n;
return a1>b1? 1:-1;
}
}
return b[i]? -1:0;
}
Mais pour accélérer le tri d'un tableau, fixez le tableau avant le tri, vous n'avez donc qu'à faire des conversions en minuscules et l'expression régulière une fois au lieu de chaque étape du tri.
function naturalSort(ar, index){
var L= ar.length, i, who, next,
isi= typeof index== 'number',
rx= /(\.\d+)|(\d+(\.\d+)?)|([^\d.]+)|(\.(\D+|$))/g;
function nSort(aa, bb){
var a= aa[0], b= bb[0], a1, b1, i= 0, n, L= a.length;
while(i<L){
if(!b[i]) return 1;
a1= a[i];
b1= b[i++];
if(a1!== b1){
n= a1-b1;
if(!isNaN(n)) return n;
return a1>b1? 1: -1;
}
}
return b[i]!= undefined? -1: 0;
}
for(i= 0; i<L; i++){
who= ar[i];
next= isi? ar[i][index] || '': who;
ar[i]= [String(next).toLowerCase().match(rx), who];
}
ar.sort(nSort);
for(i= 0; i<L; i++){
ar[i]= ar[i][1];
}
}