Я хотел бы отсортировать массив строк (в javascript) так, чтобы группы цифр в строках сравнивались как целые числа, а не строки. Я не беспокоюсь о числах со знаком или с плавающей запятой.
например, результат должен быть ["a1b3","a9b2","a10b2","a10b11"]
, а не ["a1b3","a10b11","a10b2","a9b2"]
Самый простой способ сделать это, кажется, разделить каждую строку на границы вокруг групп цифр. Есть ли шаблон, который я могу передать String.split для разделения по границам символов без удаления каких-либо символов?
"abc11def22ghi".split(/?/) = ["abc","11","def","22","ghi"];
Или есть другой способ сравнения строк, который не включает их разбиение, возможно, добавляя все группы цифр начальными нулями, чтобы они были одинаковой длины?
"aa1bb" => "aa00000001bb", "aa10bb" => "aa00000010bb"
Я работаю с произвольными строками, а не со строками, которые имеют определенное расположение групп цифр.
Edit:
Мне нравится /(\d+)/
один вкладыш от Gaby для разделения массива. Насколько это обратно совместимо?
Решения, которые разбирают строки один раз так, чтобы их можно было использовать для восстановления оригиналов, намного эффективнее, чем эта функция сравнения. Ни один из ответов не обрабатывает некоторые строки, начинающиеся с цифр, а другие нет, но это было бы достаточно легко исправить, и это не было явно в исходном вопросе.
["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();
результат: "!!,9,9.5,10,a3,a3b,a3b3,a3b20,a3b100,a20,a100,~~"