最近开发中用到了数据的排序场景,我第一时间就想到了javascript的sort函数,在日常中一般用于升序和降序排列,非常简单好用。对于多个条件的排序,依然很方便。
一、sort函数的基本功能
1、语法
1
2
3
4
5
6
7
8
9
arr.sort([compareFunction])
参数:
compareFunction [可选]
用于数组排序规则的比较函数。如果不含有该参数,数组元素按照转换字符串的各个字符的Unicode编码顺序进行排序。
compareFunction 参数:
firstElement 用于比较的第一个元素
secondElement 用于比较的第二个元素
返回值:
排序后的数组,返回的是当前数组。
2、没有参数的默认排序
当没有参数传入时 默认按照数组转成字符串后的结果每一位的Unicode编码进行排序
1
2
3
let arr = [311,43,54,4,40,26,31,33];
arr.sort();
console.log(arr); // [26,31,311,33,4,40,43,54]
3、升序排列
1
2
3
let arr = [311,43,54,4,40,26,31,33];
arr.sort((a,b) => b - a);
console.log(arr); // [311,54,43,40,33,31,26,4]
4、排序规则
如果添加了 compareFunction 那么数组会按该函数的返回值结果进行排序,即 compareFunction(a,b) 表示 a,b的比较结果,规则如下:
- 如果返回值结果小于0,则a和b的顺序不变;
- 如果返回值结果等于0,则a和b的顺序不变;
- 如果返回值的结果大于0,a和b会交换位置。
了解了以上排序结果以后我们可以使用sort方法颠倒数组的顺序(实现类似于reverse方法的效果)
1
2
3
let arr = [311,43,54,4,40,26,31,33];
arr.sort(() => -1);
console.log(arr); // [33, 31, 26, 40, 4, 54, 43, 311]
5、随机排序
1
2
3
let arr = [311,43,54,4,40,26,31,33];
arr.sort((a,b) => Math.random() - 0.5);
console.log(arr); // 结果为随机排序
6、按照对象指定的属性值进行升序或降序排列
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var arr = [{
name: 'zhangsan',
age: 20
}, {
name: 'lisi',
age: 15
}, {
name: 'wangwu',
age: 17
}, {
name: 'zhaoliu',
age: 23
}, {
name: 'fengqi',
age: 31
}, {
name: 'xiaoming',
age: 11
}];
function sortby(prop, rev = true) {
// prop 属性名
// rev 升序降序 默认升序
return function(a, b) {
var val1 = a[prop];
var val2 = b[prop];
return rev ? val1 - val2 : val2 - val1;
}
}
arr.sort(sortby('age')); // 根据age进行升序排列
arr.sort(sortby('age',false)); // 根据age进行降序排列
二、复杂一点的排序
1、中文汉字按照拼音排序
String.prototype.localeCompare
在不考虑多音字的前提下,基本可以完美实现按照拼音排序
1
2
3
4
5
// 拼音首字母 jia 在前, kai 在后
'开'.localeCompare('驾'); //-1;
// 确认之后是 localeCompare 需要明确指定 locales 参数
'开'.localeCompare('驾', 'zh'); //1
2、先按奇数升序排列,后按偶数升序排列
1
2
3
4
5
6
7
let arr = [311,43,54,4,40,26,31,33];
arr.sort((a,b)=>{
if(!(a % 2) && b % 2) return 1; // 首先满足条件a为偶数,b为奇数
if((a % 2 && b % 2 || !(a % 2) && !(b % 2)) && a > b) return 1; // 判断a b 均为奇数或偶数 且a > b 即可进行升序排序
return -1;
});
console.log(arr); // [31, 33, 43, 311, 4, 26, 40, 54]
三、项目实践
1、项目要求
故障分为:严重故障、较大故障和一般故障, 故障又分为是否超时。
排序要求:按照故障等级排序,同一故障等级下超时的在最前面。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
let a = [
{
name: '故障1',
level: '一般故障',
timeOut: true,
customer: 2
},{
name: '故障1',
level: '一般故障',
timeOut: false,
customer: 2
},{
name: '故障2',
level: '较大故障',
timeOut: false,
customer: 2
},{
name: '故障3',
level: '严重故障',
timeOut: true,
customer: 4
},{
name: '故障4',
level: '严重故障',
timeOut: true,
customer: 3
},{
name: '故障5',
level: '较大故障',
timeOut: true,
customer: 1
},
]
let faultType={
严重故障:3,
较大故障:2,
一般故障:1
}
let ret = a.sort((a,b)=>{
if(faultType[b.level] > faultType[a.level]){
return 1
}else if(faultType[b.level] == faultType[a.level] && b.timeOut==true&&a.timeOut==false){
return 1
}
return -1
})
console.log(ret)
如果数据中加入涉及客户,排序:涉及客户、故障等级、是否超时,这样排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let ret2 = a.sort((a,b)=>{
if(b.customer > a.customer){
return 1
}else if(b.customer == a.customer){
if(faultType[b.level] > faultType[a.level]){
return 1
}else if(faultType[b.level] == faultType[a.level]){
if(b.timeOut==true&&a.timeOut==false){
return 1
}
}
}
return -1
})
console.log(ret2)
// 输出
(6) [{…}, {…}, {…}, {…}, {…}, {…}]
0: {name: '故障3', level: '严重故障', timeOut: true, customer: 4}
1: {name: '故障4', level: '严重故障', timeOut: true, customer: 3}
2: {name: '故障2', level: '较大故障', timeOut: false, customer: 2}
3: {name: '故障1', level: '一般故障', timeOut: true, customer: 2}
4: {name: '故障1', level: '一般故障', timeOut: false, customer: 2}
5: {name: '故障5', level: '较大故障', timeOut: true, customer: 1}