一、基本使用
const arrNum=[5,3,6,100,6,7];
Array类型的对象都有sort方法。当定义了如上的arrNum,可以直接使用sort方法,例
注意:sort方法是会影响源数据的
sort方法中可以传入一个“compareFunction”,函数有两个参数a、b,表示在sort排序过程中一组组做对比的前后两个对象。可以理解为遍历中的“i”和“i+1”。
arrNum.sort(function(a,b){ // 升序写法
if(a < b){
return -1;
}
if(a > b){
return 1;
}
if(a === b){
return 0;
}
})
在compareFunction函数里,return的值“x”,有如下规则
1、x<0时则会将a移动到b前面。2、x>0时则会将a移动到b后面。3、如果x=0则位置不变。
所以上面代码可以简写如下:a、b前后两数相减,正数表示原来顺序在前的比后面的大,则会后移一位。依次比较下去则完成了升序。
arrNum.sort(function(a, b){ // 升序写法
return a - b;
});
//附:箭头函数更简化,不懂得自行了解
//arrNum.sort((a, b)=> a - b);
要做降序,函数接收参数时,只需要把a、b的声明换个位置,如compareFunction(b,a)
二、对象排序
const arrObj=[{
name:'史密斯',
age:18,
birthday:'2003-01-08'
},{
name:'丹妮',
age:16,
birthday:'2005-06-08'
},{
name:'艾米',
age:24,
birthday:'1997-07-08'
}];
这时的a、b就是对象数组中的某两个对象元素,均可以点到其元素的属性。如下拿年龄升序
arrObj.sort((a,b)=> a.age - b.age);
三、时间、中文排序
在上面的对象排序中存在时间和中文,无法直接相减做排序,需要特殊处理
1)Date类型把他转化为时间戳,就是一串数字,就可以按数字排序了,例
arrObj.sort((a,b)=> { // 升序
return new Date(a.birthday).getTime() - new Date(b.birthday).getTime();
});
2)中文则需要利用localeCompare()函数比较两个字符在字母表中排序,如果String a在Param b前则返回-1,相等则0,否则1。
arr.sort((a, b) => { // Z-A排序
return a.name.localeCompare(b.name, 'zh');
});
注意 :按localeCompare来比较中文会有bug:多音字的问题,长沙,重庆这种,系统取的是zhang和zhong的拼音。所以导致排序时这种字会垫底。
四、实用封装
/**对对象数组排序
*arr:要排序的数据源,key:数据源中排序的键名,type:排序方式(默认升序)
*/
function sortObjArr(arr, key, type = 'asc', special = 'emptyAfter') {
if(arr&&arr.length){
const noNullObj=arr.find(x=>x[key]); // 找一个不为空的该字段的对象
if (isDate(noNullObj[key])) { // 日期时间类型
// ||/^(date|time)|(date|time)$/gi.test(str) // 或者说这个字段名包含了date或者time
arr.sort((a, b) => {
if (type === 'asc') { // 升序
return new Date(a[key]).getTime() - new Date(b[key]).getTime();
}
return new Date(b[key]).getTime() - new Date(a[key]).getTime();
});
} else if (isNaN(noNullObj[key])) { // 中文或字母等
arr.sort((a, b) => {
if (type === 'desc') { // 降序
return a[key].localeCompare(b[key],'zh');
}
return b[key].localeCompare(a[key],'zh');
});
} else {// 其他数值
arr.sort((a, b) => {
if (type === 'asc') {
return a[key] - b[key];
}
return b[key] - a[key];
});
}
}
if(special==='emptyAfter'){// 空值移到最后
arr.sort((a,b)=>{
if(a[key] && b[key]){
return 0;
}
return -1; // 有一个为空则往后移
});
}
return arr;
}
sortObjArr(arrObj,'name','desc');
console.log('名字降序',arrData);
function isDate(str){ // 判断是否日期
if(str instanceof Date // 是原始日期类型
||(/^\d{4}(-|\/){1}\d{1,2}(-|\/){1}\d{1,2}/.test(str)&&new Date(str))
){ // 符合正则的2021-01-02
return true;
}
return false;
}