原文:Sorting an Array in JavaScript
学习如何使用JavaScript内置的Array#sort()函数。
JavaScript的内置sort()函数对初学者来说很奇怪。例如,对以下数组进行排序:
输出是什么呢?你可能认为数组会保持不变,但实际输出是这样的:
因为JavaScript会先把数组元素转换为字符串,然后根据JavaScript的字符串顺序进行排序。
数值数组排序
sort()
函数接收一个参数,compareFunction()
——对比函数。compareFunction()
函数接收两个数组元素a
和b
。它返回:
- 如果
a < b
则返回负数
- 如果
a > b
则返回正数
- 如果
a
既不大于也不小于b
则返回0
要按正序对一个数值数组排序,compareFunction()
应该为(a, b) => a - b
。
1 2 3 4
| const arr = [3, 20, 100];
arr.sort((a, b) => a - b); arr;
|
要按倒序对一个数值数组排序,应该使用(a, b) => b - a
。
1 2 3 4
| const arr = [20, 3, 100];
arr.sort((a, b) => b - a); arr;
|
如果你对Java比较熟悉,可以认为compareFunction()
和compareTo()
起差不多的作用。
对象数组根据对象属性排序
假设你需要对一个对象数组进行排序。例如,有一份《星际旅行——下一代》的角色表:
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 } ];
|
使用JavaScript的字符串比较,按照lastName
对characters
数组进行排序:
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; });
characters;
|
按age
对characters
数组进行排序:
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);
characters;
|
如何按rank
(军衔)排序呢?按军衔排序需要自定义顺序,因为JavaScript环境不知道'Captain'
是比'Lieutenant'
更高的军衔。使用Map
自定义顺序可以实现军衔排序:
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); });
characters;
|