【发布时间】:2011-12-27 18:41:00
【问题描述】:
我想对字符串数组(在 javascript 中)进行排序,以便将字符串中的数字组作为整数而不是字符串进行比较。我不担心有符号数或浮点数。
例如,结果应该是["a1b3","a9b2","a10b2","a10b11"] 而不是["a1b3","a10b11","a10b2","a9b2"]
执行此操作的最简单方法似乎是将每个字符串拆分为围绕数字组的边界。是否有一种模式可以传递给 String.split 以在字符边界上拆分而不删除任何字符?
"abc11def22ghi".split(/?/) = ["abc","11","def","22","ghi"];
或者是否有另一种方法来比较不涉及拆分字符串的字符串,例如用前导零填充所有数字组,使它们的长度相同?
"aa1bb" => "aa00000001bb", "aa10bb" => "aa00000010bb"
我正在处理任意字符串,而不是具有特定数字组排列的字符串。
编辑:
我喜欢 Gaby 的 /(\d+)/ 一个衬垫来拆分阵列。向后兼容的程度如何?
以可用于重建原始字符串的方式解析字符串一次的解决方案比此比较功能更有效。没有一个答案处理一些以数字开头的字符串,而另一些则不是,但这很容易补救,并且在原始问题中并不明确。
["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,~~"
【问题讨论】:
-
非数字部分是否始终相同?如果不是,排序算法是否应该按 ASCII 顺序对它们进行排序?
-
在您的示例中,提取的是 13、92、102、1011?还是更像 1.3、9.2、10.2、10.11?我的意思是第一个数字更重要还是忽略了字母?
-
...哦,您还想对非整数进行排序,我现在明白了...
标签: javascript regex sorting split natural-sort