JavaScript对象数组排序

JavaScript的内置sort函数可以用属性将对象数组进行排序。

有一个JavaScript数组,其中是《星际迷航:下一代》的演员表:

1
2
3
4
5
const characters = [
{ firstName: 'Jean-Luc', lastName: 'Picard', rank: 'Captain', age: 59 },
{ firstName: 'Will', lastName: 'Riker', rank: 'Commander', age: 29 },
{ firstName: 'Geordi', lastName: 'La Forge', rank: 'Lieutenant', age: 29 }
];

如何按不同属性进行排序呢?

按age排序

内置的Array#sort()函数可以接收一个回调参数,用于比较数组中的两个元素。

回调函数compareFunction()接收2个参数ab,如果compareFunction(a, b)返回小于0的值,JavaScript认为ab小,如果返回大于0的值,认为ab大。

这就很容易按数值属性排序,比如age。如果a.age - b.age < 0b就比a要年龄大。

1
2
3
4
5
6
7
8
9
10
const characters = [
{ firstName: 'Jean-Luc', lastName: 'Picard', rank: 'Captain', age: 59 },
{ firstName: 'Will', lastName: 'Riker', rank: 'Commander', age: 29 },
{ firstName: 'Geordi', lastName: 'La Forge', rank: 'Lieutenant', age: 29 }
];

characters.sort((a, b) => a.age - b.age);

// Riker, La Forge, Picard
characters;

按lastName排序

按字符串属性排序也很简单,比如lastName。因为JavaScript的<>可以比较字符串。按字符串属性排序,compareFunction()可以用<比较两个字符串:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const characters = [
{ firstName: 'Jean-Luc', lastName: 'Picard', rank: 'Captain', age: 59 },
{ firstName: 'Will', lastName: 'Riker', rank: 'Commander', age: 29 },
{ firstName: 'Geordi', lastName: 'La Forge', rank: 'Lieutenant', age: 29 }
];

characters.sort((a, b) => {
if (a === b) {
return 0;
}
return a.lastName < b.lastName ? -1 : 1;
});

// La Forge, Picard, Riker
characters;

按rank排序

rank排序比较难一些,因为rank并非按字母表顺序,而JavaScript不知道Captain比Lieutenant级别高。

要按这种自定义顺序排序,要定义rank到数值的映射,这样更容易比较。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const characters = [
{ firstName: 'Jean-Luc', lastName: 'Picard', rank: 'Captain', age: 59 },
{ firstName: 'Will', lastName: 'Riker', rank: 'Commander', age: 29 },
{ firstName: 'Geordi', lastName: 'La Forge', rank: 'Lieutenant', age: 29 }
];

const rankOrder = new Map([
['Captain', 1],
['Commander', 2],
['Lieutenant', 3]
]);

characters.sort((a, b) => {
return rankOrder.get(a.rank) - rankOrder.get(b.rank);
});

// Picard, Riker, La Forge
characters;