在JavaScript中,数组排序是一个常见且强大的操作。虽然JavaScript提供了默认的排序方法sort()
,但很多时候我们需要根据特定需求对数组进行自定义排序。这时,自定义比较函数就派上用场了。
基本排序方法
JavaScript的Array.prototype.sort()
方法默认将元素转换为字符串,然后按照UTF-16代码单元值序列进行排序:
javascript
const fruits = ['banana', 'apple', 'cherry'];
fruits.sort();
console.log(fruits); // ['apple', 'banana', 'cherry']
对于数字排序,默认行为可能不符合预期:
javascript
const numbers = [10, 5, 40, 25];
numbers.sort();
console.log(numbers); // [10, 25, 40, 5] - 不是我们想要的数字顺序
自定义比较函数
为了正确排序数字或其他复杂数据类型,我们需要提供自定义比较函数。比较函数接收两个参数(通常称为a和b),并根据以下规则返回值:
- 如果a应该排在b前面,返回负数(通常-1)
- 如果a应该排在b后面,返回正数(通常1)
- 如果a和b相等,返回0
数字排序
javascript
const numbers = [10, 5, 40, 25];
numbers.sort((a, b) => a - b);
console.log(numbers); // [5, 10, 25, 40] - 升序
numbers.sort((a, b) => b - a);
console.log(numbers); // [40, 25, 10, 5] - 降序
对象数组排序
当排序对象数组时,比较函数可以基于对象属性:
javascript
const users = [
{ name: 'John', age: 25 },
{ name: 'Jane', age: 20 },
{ name: 'Bob', age: 30 }
];
// 按年龄升序
users.sort((a, b) => a.age - b.age);
// 按名字字母顺序
users.sort((a, b) => a.name.localeCompare(b.name));
多条件排序
有时我们需要基于多个属性进行排序:
javascript
const products = [
{ name: 'Laptop', price: 1000, stock: 5 },
{ name: 'Phone', price: 500, stock: 10 },
{ name: 'Tablet', price: 500, stock: 3 }
];
// 先按价格升序,价格相同则按库存降序
products.sort((a, b) => {
if (a.price !== b.price) {
return a.price - b.price;
}
return b.stock - a.stock;
});
注意事项
-
原地排序:
sort()
方法会修改原数组,如果需要保留原数组,可以先创建副本:javascriptconst sorted = [...array].sort(compareFunction);
-
稳定性:从ES2019开始,JavaScript要求排序算法是稳定的(相同元素保持原始顺序)
-
性能:对于大型数组,自定义比较函数的性能可能成为瓶颈,需要考虑优化
高级用法
按字符串长度排序
javascript
const words = ['apple', 'banana', 'cherry', 'date'];
words.sort((a, b) => a.length - b.length);
按自定义顺序排序
javascript
const priority = ['high', 'medium', 'low'];
const tasks = [
{ title: 'Task 1', priority: 'medium' },
{ title: 'Task 2', priority: 'high' },
{ title: 'Task 3', priority: 'low' }
];
tasks.sort((a, b) => priority.indexOf(a.priority) - priority.indexOf(b.priority));
自然排序(数字在字符串中)
javascript
const files = ['file1', 'file10', 'file2', 'file20'];
files.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
// ['file1', 'file2', 'file10', 'file20']
掌握自定义比较函数的使用,可以让你在JavaScript中灵活处理各种复杂的排序需求,大大提升数组操作的效率和精确度。