您的位置:首页 > Web前端 > JavaScript

详解 JS 的 sort() 排序

2018-01-24 19:16 344 查看
前言

      sort() 排序在实际项目中是经常用到的。刚项目中遇到比较复杂数据的排序,写点东西,记一下心得。

心得

      1. sort() 默认是升序,排序会修改原数据,也会返回一个新数组。        

      2. sort() 排序底层是按照 ASCII 码大小(MDN 上写着是按照 Unicode 码)来排序的,sort 底层自动会进行循环比较。

      3. 也可以在 sort() 方法里传入比较器函数自定义比较规则。

arr.sort((a,b) => {
//内部只要写比较 a,b 的代码逻辑就可以了。
//可以用 return 1 来交换2个元素位置,return -1 不做交换。
})
Examples:

1. 纯数字数组,纯数字字符串数组或组合数组排序

const arr = [9,43,22,100];  //或 ['9','43','22','100']
let newArr = arr.sort();
console.log(newArr)  //[100, 22, 43, 9]
纯数字数组,纯数字字符串数组或组合不传比较器直接用 sort() 排序,是按照元素的第一位的大小进行排序的,并不是我们想要的结果。

如果想要按数字大小排列就得传入比较器函数。

const arr = [91,42,61,22];
let newArr = arr.sort((a,b) => {
return a-b; //升序
//    return b-a; //倒序
//    return Math.random()>.5 ? -1 : 1; //乱序
});
console.log(newArr)

2. 由字母和数字字符串组成的数组排序

字符串排序,sort() 会先对字符串的第一位的 Unicode 码进行对比,如果一样依次比较第二位,第三位...

升序直接使用 sort() 方法就行

const arr = ["a","d","fa","5","t","fw2","a31","b","e","2fs","4","0",'z9z','z6n','ng','af','7a']
let newArr = arr.sort();
console.log(newArr)

传入比较器函数可以按降序排列

const arr = ["a","d","fa","5","t","fw2","b","e","2fs","4",'z9z','z6n','af','7a'];

let newArr = arr.sort((a,b) => {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
});

console.log(newArr)  //["2fs", "4", "5", "7a", "a", "af", "b", "d", "e", "fa", "fw2", "t", "z6n", "z9z"]

字符串比大小 < >,是按照字符串的 Unicode 码大小进行比较的。

这是网上找的一个例子,把数字的排序放到字母后面

function mySorter(a, b){
if (/^\d/.test(a) ^ /^\D/.test(b)) return a>b?1:(a==b?0:-1); //^是位运算,左右两边不相等返回1,相等返回0
return a>b?-1:(a==b?0:1);
}
const pyArray=["a","d","fa","5","t","fw2","a31","b","e","2fs","4","0"]
console.log((pyArray.sort(mySorter)))
3. 汉语按照拼音首字母排序

a.localeCompare(b [, locales [, options]]) 方法会按照当地的规则,采用底层操作系统提供的排序规则进行比较。返回一个数字,a 在 b 之前返回负数,a 在 b 之后返回正数,相等返回0。可以用此方法给汉语排序。

兼容 IE11。

const arr = ['中国','红火','大爷','大大','阿里'];
let newArr = arr.sort((a,b) => {
return a.localeCompare(b, 'zh-Hans-CN', {sensitivity: 'accent'});
});
console.log(newArr)  //["阿里", "大大", "大爷", "红火", "中国"]

4. 数字字符串、字母、汉语和标点混合字符串数组排序

这里的字符串是包含标点,数字字符串,大小写字母,汉字混合类型的字符串。

const rooms = [
{name: "-100"},
{name: "1-00"},
{name: "111"},
{name: "103"},
{name: "101"},
{name: "%202"},
{name: "?"},
{name: "1?"},
{name: "%3"},
{name: "@"},
{name: "Z"},
{name: "D"},
{name: "y"},
{name: "d"},
{name: "是"},
{name: "啊"},
{name: "201他"},
];

rooms.sort(locale);
console.log(rooms);

function locale(a, b) {
return a.name.localeCompare(b.name, 'zh-Hans-CN', {sensitivity: 'variant'});
}
这种方法排出的默认顺序是:符号,数字0-9,汉字,小写在前大写在后字母Aa-Zz。

自定义的排序顺序:空字符串,数字,大写,小写,汉字,标点及特殊字符。

(感觉应该还有很多可以优化的地方):
//空-1,数字字母1,汉字2,符号3
const standard = /[a-zA-Z0-9]/; //1
const hanzi = /[\u4e00-\u9fa5]/; //2

const rooms = [
{name: "-100"},
{name: "1-00"},
{name: "111"},
{name: "103"},
{name: "101"},
{name: "?"},
{name: "1?"},
{name: "%3"},
{name: "@"},
{name: "Z"},
{name: "大"},
{name: "D"},
{name: "y"},
{name: "d"},
{name: "是"},
{name: "啊"},
{name: "201他"},
{name: "201按"},
];

rooms.sort(sortFunc);
console.log(rooms);

function sortFunc(a, b) {
a = a.name;
b = b.name;

let max = a.length;
if(b.length > max) {
max = b.length;
}

for(let i=0; i<max; i++) {
if(type(a[i]) > type(b[i])) {
return 1;
}else if(type(a[i]) === type(b[i])){
if(a[i] !== b[i]) {
if(type(a[i]) === 1 || type(a[i]) === 3) {
if(a[i] > b[i]) {
return 1;
}else if(a[i] < b[i]) {
return -1;
}
}else if(type(a[i]) === 2) {
return a[i].localeCompare(b[i], 'zh-Hans-CN', {sensitivity: 'accent'})
}
}
}else {
return -1;
}
}
}

//判断当前位的字符串的类型
function type (str) {
let n;
if(!str) {
n = -1;
}else if(standard.test(str)) {
n = 1;
}else if(hanzi.test(str)) {
n = 2;
}else {
n = 3;
}
return n;
}有不足的地方欢迎大家评论。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: