如何使用JavaScript/jQuery正确排序带连字符的数字字符串数组?
解决数组按连字符前数字排序的问题
这问题我之前也碰到过,原因很简单:JavaScript默认的Array.sort()方法是把数组元素转换成字符串后,按Unicode编码顺序来排序的,而不是按我们直觉里的数字大小排序。所以像'12'会排在'2'前面,因为字符'1'的Unicode码点比'2'小,这就是你用默认sort()得不到预期结果的原因。
要实现你想要的排序效果,我们需要给sort()方法传一个自定义比较函数,告诉它怎么去比较数组里的元素。具体步骤如下:
1. 提取每个字符串中连字符前的数字
我们可以用split('-')把每个字符串按连字符拆分成数组,取第一个元素就是我们要用来排序的数字部分,再用parseInt()把它转换成整数。
2. 编写比较函数
比较函数需要返回一个数值:
- 如果返回负数,说明
a应该排在b前面 - 如果返回正数,说明
b应该排在a前面 - 如果返回0,两者顺序不变
完整代码示例
var fruits = ['0-2','1-1','12-2','14-2','2-3','21-1','4-1']; // 自定义排序函数 fruits.sort(function(a, b) { // 提取连字符前的数字并转成整数 const numA = parseInt(a.split('-')[0], 10); const numB = parseInt(b.split('-')[0], 10); // 通过数字差值确定排序顺序 return numA - numB; }); // 输出结果 console.log(fruits.join(',')); // 0-2,1-1,2-3,4-1,12-2,14-2,21-1
如果想用更简洁的ES6箭头函数写法,也可以这样:
fruits.sort((a, b) => parseInt(a.split('-')[0], 10) - parseInt(b.split('-')[0], 10));
扩展:如果连字符后的数字也需要排序
要是以后遇到前面数字相同的情况,想再按连字符后面的数字排序,可以扩展比较函数:
fruits.sort((a, b) => { // 把两个部分都转成整数 const [numA1, numA2] = a.split('-').map(num => parseInt(num, 10)); const [numB1, numB2] = b.split('-').map(num => parseInt(num, 10)); // 先比较前面的数字 if (numA1 !== numB1) { return numA1 - numB1; } // 前面数字相同的话,再比较后面的数字 return numA2 - numB2; });
内容的提问来源于stack exchange,提问作者ravi
相关产品推荐
相关产品推荐

