按字符串属性值对对象数组进行排序

按字符串属性值对对象数组进行排序

技术背景

在 JavaScript 开发中,经常会遇到需要对对象数组按照某个字符串属性值进行排序的需求。例如,对用户列表按照姓氏排序,对商品列表按照名称排序等。JavaScript 提供了 Array.prototype.sort() 方法来实现排序,同时也有许多不同的方式可以实现按字符串属性值排序。

实现步骤

自定义比较函数

可以编写自定义的比较函数来实现排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function compare(a, b) {
if (a.last_nom < b.last_nom) {
return -1;
}
if (a.last_nom > b.last_nom) {
return 1;
}
return 0;
}

const objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];

objs.sort(compare);
console.log(objs);

内联比较函数

可以使用内联的箭头函数来简化代码。

1
2
3
4
5
6
7
8
const objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];

objs.sort((a, b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0));
console.log(objs);

动态排序函数

可以创建一个动态排序函数,根据传入的属性名进行排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function dynamicSort(property) {
let sortOrder = 1;
if (property[0] === "-") {
sortOrder = -1;
property = property.substr(1);
}
return function (a, b) {
const result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
return result * sortOrder;
};
}

const People = [
{ Name: "Name", Surname: "Surname" },
{ Name: "AAA", Surname: "ZZZ" },
{ Name: "Name", Surname: "AAA" }
];

People.sort(dynamicSort("Name"));
People.sort(dynamicSort("Surname"));
People.sort(dynamicSort("-Surname"));
console.log(People);

多参数排序函数

可以创建一个多参数排序函数,根据多个属性进行排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function dynamicSortMultiple() {
const props = arguments;
return function (obj1, obj2) {
let i = 0, result = 0, numberOfProperties = props.length;
while (result === 0 && i < numberOfProperties) {
result = dynamicSort(props[i])(obj1, obj2);
i++;
}
return result;
};
}

const People = [
{ Name: "Name", Surname: "Surname" },
{ Name: "AAA", Surname: "ZZZ" },
{ Name: "Name", Surname: "AAA" }
];

People.sort(dynamicSortMultiple("Name", "-Surname"));
console.log(People);

使用 ES6 的 localeCompare 方法

在 ES6 及以后的版本中,可以使用 localeCompare 方法进行排序。

1
2
3
4
5
6
7
8
const objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];

objs.sort((a, b) => a.last_nom.localeCompare(b.last_nom));
console.log(objs);

使用 Underscore.js 或 Lodash

可以使用 Underscore.js 或 Lodash 库来实现排序。

1
2
3
4
5
6
7
8
9
const _ = require('lodash');
const objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];

const sortedObjs = _.sortBy(objs, 'last_nom');
console.log(sortedObjs);

使用 Intl.Collator 进行自然排序

当需要进行自然字符串排序时,可以使用 Intl.Collator

1
2
3
4
5
6
7
8
9
10
11
12
13
const files = [
{ name: "1.mp3", size: 123 },
{ name: "10.mp3", size: 456 },
{ name: "100.mp3", size: 789 },
{ name: "11.mp3", size: 123 },
{ name: "111.mp3", size: 456 },
{ name: "2.mp3", size: 789 }
];

const naturalCollator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' });

files.sort((a, b) => naturalCollator.compare(a.name, b.name));
console.log(files);

核心代码

以下是一些核心代码示例:

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
// 自定义比较函数
function compare(a, b) {
if (a.last_nom < b.last_nom) {
return -1;
}
if (a.last_nom > b.last_nom) {
return 1;
}
return 0;
}

// 动态排序函数
function dynamicSort(property) {
let sortOrder = 1;
if (property[0] === "-") {
sortOrder = -1;
property = property.substr(1);
}
return function (a, b) {
const result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
return result * sortOrder;
};
}

// 多参数排序函数
function dynamicSortMultiple() {
const props = arguments;
return function (obj1, obj2) {
let i = 0, result = 0, numberOfProperties = props.length;
while (result === 0 && i < numberOfProperties) {
result = dynamicSort(props[i])(obj1, obj2);
i++;
}
return result;
};
}

// 使用 ES6 的 localeCompare 方法
const objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];

objs.sort((a, b) => a.last_nom.localeCompare(b.last_nom));

最佳实践

  • 当排序逻辑简单时,使用内联箭头函数可以简化代码。
  • 当需要根据不同属性动态排序时,使用动态排序函数。
  • 当需要根据多个属性排序时,使用多参数排序函数。
  • 在 ES6 及以后的版本中,优先使用 localeCompare 方法进行字符串排序。
  • 如果项目中已经使用了 Underscore.js 或 Lodash 库,可以使用它们提供的排序方法。

常见问题

大小写敏感问题

默认的比较函数是大小写敏感的。如果需要忽略大小写,可以在比较时将字符串转换为小写或大写。

1
2
3
4
5
6
7
8
const arr = [
{ name: 'Apple' },
{ name: 'banana' },
{ name: 'Cherry' }
];

arr.sort((a, b) => a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1);
console.log(arr);

排序稳定性问题

JavaScript 的 Array.prototype.sort() 方法在不同浏览器中的排序稳定性可能不同。如果需要稳定排序,可以使用第三方库或自定义排序算法。


按字符串属性值对对象数组进行排序
https://119291.xyz/posts/2025-05-09.sort-array-of-objects-by-string-property-value/
作者
ww
发布于
2025年5月9日
许可协议