室友今天问我一个 JS 的排序问题,总的来说是把类似:
var arr = ["分类82", "分类17", "分类8", "分类69", "分类43", "分类1"]
排序成:
["分类1", "分类8", "分类17", "分类43", "分类69", "分类82"]
JS里面数组排序用到的是 Array.prototype.sort() 的方法,而这个方法默认把元素都转成了字符串实现排序。
The default sort order is built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.
中文按照字符顺序排,数字则按照数字的顺序,而不是 1, 11, 2, 21, 3... 这样按字符为单位的顺序。
大概把我想到的思路总结一下:
自定义排序需要传入一个用作比较的函数 compareFunction(a, b),所以这里的思路重点在于写出一个根据元素得出先后的算法:
假设几个输入和输出:
input:11, 2
output:任意大于0的数值
input:a11, a2
output:任意大于0的数值
input: a2333, b12
output: 任意小于0的数值
......
然后,这个函数里面,正则匹配数字与非数字,非数字部分不相等时候,用 localeCompare 方法,若非数字部分相同,则返回数字部分的计算结果。
得出如下代码:
var arr = ["分类82", "分类17", "分2类8", "分类69", "分类43", "分类1"];
arr.sort(function (a, b) {
var _a = a.match(/^(.*?)(\d*)$/);
var _b = b.match(/^(.*?)(\d*)$/);
if (_a[1] === _b[1]) {
return parseInt(_a[2] || 0) - parseInt(_b[2] || 0);
} else {
return _a[1].localeCompare(_b[1]);
}
})
在这里也留下一个记录~