js对象数组sort按需排序
# js对象数组sort按需排序
# 一、起因
今天遇到一个需求:
对一个对象数组排序,排序字段是对象的enable字段 boolean 类型, taskId字段 类型 string | null
const list = [
{
"label": "区域数人(arm)",
"algorithmCode": "areaCountDeepGlint",
"taskId": "1465590538420891670",
"enabled": true,
"synzInd": 0,
"version": "V21.11.14.2"
},
{
"label": "人员倒地(arm)",
"algorithmCode": "fallGlint",
"taskId": null,
"enabled": true,
"synzInd": 0,
"version": "V21.11.14.2"
},
{
"label": "烟雾火苗(arm)",
"algorithmCode": "smokeGlint",
"taskId": "1465590534420891670",
"enabled": false,
"synzInd": 0,
"version": "V21.11.14.2"
}
]
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
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
需求:开启的(enabled)排最前面,然后是有taskId的, 最后是taskId为null的
尝试用js的原生sort方法来解决问题,有两个疑问
- 布尔类型怎么比较
- string类型和null怎么比较
我们先看看sort的函数签名
arr.sort([compareFunction])
1
可以看到,sort函数传入的回掉函数compareFunction的参数比较,决定了排序的结果,规则如下
先考虑enabled字段排序,为true的排前面,false排后面
这里可以巧用JavaScript的类型转换,布尔类型参与减法运算时:
True 会转化为 1
false 会转化为 0
list.sort((a, b) => {
return b.enabled - a.enabled
})
1
2
3
4
2
3
4
这里有四种情况
根据上图可知
当比较时,如果布尔值相同,会保持和原始的顺序,当值不同时,为true的将排在前面
所以我们得到的是开启(enabled字段为true)排在前面的稳定排序的序列
然后考虑taskId字段排序
同理,利用js的类型转换特性
null类型 参与减法运算时将转换为数字0
数字字符串将转换为数字
最后解决方法为:
const sortedList = list
.sort((a, b) => {
return b.taskId - a.taskId
})
.sort((a, b) => {
return b.enabled - a.enabled
})
1
2
3
4
5
6
7
2
3
4
5
6
7
结果
[
{
"label": "区域数人(arm)",
"algorithmCode": "areaCountDeepGlint",
"taskId": "1465590538420891670",
"enabled": true,
"synzInd": 0,
"version": "V21.11.14.2"
},
{
"label": "人员倒地(arm)",
"algorithmCode": "fallGlint",
"taskId": null,
"enabled": true,
"synzInd": 0,
"version": "V21.11.14.2"
},
{
"label": "烟雾火苗(arm)",
"algorithmCode": "smokeGlint",
"taskId": "1465590534420891670",
"enabled": false,
"synzInd": 0,
"version": "V21.11.14.2"
}
]
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
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
完美解决需求
# 二、总结
JavaScript的类型转换有时会带来预期之外的bug,不过巧秒利用的话,也挺有意思
上次更新: 2023/04/05, 09:41:10