0%

针对对象数组进行多重排序

快捷通道

如果你的数组的多重排序需求是写死的,可以使用 thenby

只需要下面几行就 ok 了

1
2
3
4
5
data.sort(
firstBy(function (v) { return v.name.length; })
.thenBy("population")
.thenBy("id")
);

场景

我们来看看,如果这个过滤规则是动态,比如 table 上面的字段过滤,我们应该如何处理

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
48
49
50
51
52
53
54
55
56

// 假设我们有一个数组 需要进行多重排序
const rows = [
{
fields: {
price: 19,
value: 8,
name: "hotdog",
},
},
{
fields: {
price: 12,
value: 2,
name: "buger",
},
},
{
fields: {
price: 19,
value: 44,
name: "coolcat",
},
},
];

// 这里的 sortConfigs 是动态的
const sortConfigs = [
{ field: "price", mode: "asc" },
{ field: "price", mode: "desc" },
];

const customSorter = function (left, right, field): number {
return left.fields[field] - right.fields[field];
};

// 这里是参考 antd vue 的思路
// https://github.com/vueComponent/ant-design-vue/blob/797a1c6c8f6757048bf7356dba935e1a9d0508ed/components/table/hooks/useSorter.tsx#L272
rows.sort((left, right) => {
for (let i = 0; i < sortConfigs.length; i++) {
const currentConfig = sortConfigs[i];
const field = currentConfig.field;
const mode = currentConfig.mode;
let res = customSorter(left, right, currentConfig.field);

// 最关键的是下面这个判断,
// for 循环会把每个排序规则都执行一遍
// 如果当前规则下,res 的值为 0 时,则进行 continue 这样下一条规则就会继续执行排序
// 如果 res 不等于 0,则代表排序已完成
if (res !== 0) {
return mode === "asc" ? res : res * -1;
}
}

return 0;
});