【JavaScript 教程】第六章 数组10— sort() : 对数组中的元素进行排序

web前端开发

共 6416字,需浏览 13分钟

 ·

2022-01-20 01:28

英文 | https://www.javascripttutorial.net/

译文 | 杨小爱

在上节,我们学习了如何使用 JavaScript Array some() 方法来检查数组中的至少一个元素是否通过了测试错过的小伙伴可以点击文章《【JavaScript 教程】第六章 数组09— some() :检查数组中是否至少有一个元素通过了测试 》进行学习。
那么,在今天的教程中,我们一起来学习如何使用 JavaScript Array sort() 方法对数字、字符串和对象数组进行排序。

JavaScript Array sort() 方法介绍

sort() 方法允许您就地对数组的元素进行排序。除了返回排序后的数组,sort() 方法还改变了元素在原始数组中的位置。

默认情况下, sort() 方法按升序对数组元素进行排序,最小值在前,最大值在后。

sort() 方法将元素转换为字符串并比较字符串以确定顺序。

考虑以下示例:

let numbers = [0, 1 , 2, 3, 10, 20, 30 ];numbers.sort();console.log(numbers);

输出是:

[ 0, 1, 10, 2, 20, 3, 30 ]

在此示例中,sort() 方法将 10 放在 2 之前,因为在进行字符串比较时,字符串“10”在“2”之前。

要解决此问题,您需要将比较函数传递给 sort() 方法。 sort() 方法将使用比较函数来确定元素的顺序。

下面说明了 sort() 方法的语法:

array.sort(comparefunction)

sort() 方法接受一个可选参数,该参数是一个比较数组两个元素的函数。

如果省略 compare 函数,sort() 方法将按照前面提到的基于元素的 Unicode 代码点值的排序顺序对元素进行排序。

sort() 方法的比较函数接受两个参数并返回一个确定排序顺序的值。 下面说明了比较函数的语法:

function compare(a,b) {  // ...}

compare() 函数接受两个参数 a 和 b。 sort() 方法将根据 compare() 函数的返回值使用以下规则对元素进行排序:

如果 compare(a,b) 小于零,sort() 方法将 a 排序到比 b 低的索引。 换句话说,a 会先出现。

如果 compare(a,b) 大于零,则 sort() 方法将 b 排序为比 a 低的索引,即 b 将排在最前面。

如果 compare(a,b) 返回零,则 sort() 方法认为 a 等于 b 并保持它们的位置不变。

要解决排序数字的问题,您可以使用以下语法:

let numbers = [0, 1 , 2, 3, 10, 20, 30 ];numbers.sort( function( a , b){    if(a > b) return 1;    if(a < b) return -1;    return 0;});
console.log(numbers);

输出:

[ 0,  1,  2, 3, 10, 20, 30 ]

或者您可以使用箭头函数语法定义比较函数:

let numbers = [0, 1 , 2, 3, 10, 20, 30 ];numbers.sort((a,b) => {    if(a > b) return 1;    if(a < b) return -1;    return 0;});
console.log(numbers);

以下是最简单的,因为数组的元素是数字:

let numbers = [0, 1, 2, 3, 10, 20, 30];numbers.sort((a, b) => a - b);
console.log(numbers);

对字符串数组进行排序

假设您有一个名为动物的字符串数组,如下所示:

let animals = [    'cat', 'dog', 'elephant', 'bee', 'ant'];

要按字母顺序对动物数组的元素进行升序排序,请使用 sort() 方法而不传递 compare 函数,如下例所示:

let animals = [    'cat', 'dog', 'elephant', 'bee', 'ant'];animals.sort();
console.log(animals);

输出:

[ 'ant', 'bee', 'cat', 'dog', 'elephant' ]

要按降序对动物数组进行排序,您需要更改比较函数的逻辑并将其传递给 sort() 方法,如下例所示。

let animals = [    'cat', 'dog', 'elephant', 'bee', 'ant'];
animals.sort((a, b) => { if (a > b) return -1; if (a < b) return 1; return 0;});
console.log(animals);

输出:

[ 'elephant', 'dog', 'cat', 'bee', 'ant' ]

假设您有一个包含大写和小写元素的数组,如下所示:

// sorting array with mixed caseslet mixedCaseAnimals = [    'Cat', 'dog', 'Elephant', 'bee', 'ant'];

要按字母顺序对此数组进行排序,您需要使用自定义比较函数将所有元素转换为相同的大小写,例如大写进行比较并将该函数传递给 sort() 方法。

let mixedCaseAnimals = [    'Cat', 'dog', 'Elephant', 'bee', 'ant'];
mixedCaseAnimals.sort(function (a, b) { let x = a.toUpperCase(), y = b.toUpperCase(); return x == y ? 0 : x > y ? 1 : -1;
});

输出:

[ 'ant', 'bee', 'Cat', 'dog', 'Elephant' ]

使用非 ASCII 字符对字符串数组进行排序

sort() 方法可以很好地处理带有 ASCII 字符的字符串。 但是,对于包含非 ASCII 字符(例如 é、è 等)的字符串,sort() 方法将无法正常工作。 例如:

let animaux = ['zèbre', 'abeille', 'écureuil', 'chat'];animaux.sort();
console.log(animaux);

如您所见,écureuil 字符串应该在 zèbre 字符串之前。

要解决此问题,您可以使用 String 对象的 localeCompare() 方法来比较特定语言环境中的字符串,如下所示:

animaux.sort(function (a, b) {    return a.localeCompare(b);});console.log(animaux);

输出:

[ 'abeille', 'chat', 'écureuill', 'zèbree' ]

animaux 数组的元素现在处于正确的顺序。

对数字数组进行排序

假设您有一个名为分数的数字数组,如下例所示。

let scores = [    9, 80, 10, 20, 5, 70];

要按数字对数字数组进行排序,您需要传入一个自定义比较函数来比较两个数字。

以下示例按数字升序对分数数组进行排序。

let scores = [    9, 80, 10, 20, 5, 70];// sort numbers in ascending orderscores.sort((a, b) => a - b);
console.log(scores);

输出:

[ 5, 9, 10, 20, 70, 80 ]

要以降序对数字数组进行排序,您只需要反转比较函数中的逻辑,如下例所示:

let scores = [    9, 80, 10, 20, 5, 70];// descending orderscores.sort((a, b) => b - a);console.log(scores);

输出:

[80, 70, 20, 10, 9, 5]

按指定属性对对象数组进行排序

下面是一个employee对象数组,其中每个对象包含三个属性:name、salary和hireDate。

let employees = [    {name: 'John', salary: 90000, hireDate: "July 1, 2010"},    {name: 'David', salary: 75000, hireDate: "August 15, 2009"},    {name: 'Ana', salary: 80000, hireDate: "December 12, 2011"}];

按数字属性对对象进行排序

以下示例显示如何salary升序对员工进行排序。

// sort by salaryemployees.sort(function (x, y) {    return x.salary - y.salary;});
console.table(employees);

输出:

此示例类似于按升序对数字数组进行排序的示例。 不同之处在于它比较了两个对象的salary属性。

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

要按name属性不区分大小写对employees数组进行排序,请传递比较两个字符串不区分大小写的比较函数,如下所示:

employees.sort(function (x, y) {    let a = x.name.toUpperCase(),        b = y.name.toUpperCase();    return a == b ? 0 : a > b ? 1 : -1;});
console.table(employees);

按日期属性对对象进行排序

假设您希望根据每个员工的雇用日期对员工进行排序。

雇用日期数据存储在雇员对象的租用日期属性中。 但是,它只是一个表示有效日期的字符串,而不是 Date 对象。

因此,要按雇用日期对员工进行排序,首先必须从日期字符串创建一个有效的 Date 对象,然后比较两个日期,这与比较两个数字相同。

这是解决方案:

employees.sort(function (x, y) {    let a = new Date(x.hireDate),        b = new Date(y.hireDate);    return a - b;});
console.table(employees);
代码语言:JavaScript ( javascript )

优化 JavaScript 数组 sort() 方法

实际上,sort() 方法为数组中的每个元素多次调用比较函数。

请参阅以下示例:

let rivers = ['Nile', 'Amazon', 'Congo', 'Mississippi', 'Rio-Grande'];
rivers.sort(function (a, b) { console.log(a, b); return a.length - b.length;});

输出:

Amazon NileCongo AmazonCongo AmazonCongo NileMississippi CongoMississippi AmazonRio-Grande AmazonRio-Grande Mississippi

它们怎么运行的:

  • 首先,声明一个由著名河流名称组成的数组 rivers。

  • 其次,使用 sort() 方法按其元素的长度对rivers数组进行排序。每当 sort() 方法调用比较函数时,我们就会将 Rivers 数组的元素输出到 Web 控制台。

如上面的输出所示,每个元素都被评估了多次,例如亚马逊 4 次,刚果 2 次等。

如果数组元素的数量增加,则可能会降低性能。

您无法减少比较函数的执行次数。但是,您可以减少比较必须执行的工作。这种技术称为施瓦兹变换。

要实现这一点,请按照以下步骤操作:

  • 首先,使用 map() 方法将实际值提取到临时数组中。

  • 其次,使用已经评估(或转换)的元素对临时数组进行排序。

  • 第三,遍历临时数组,得到一个顺序正确的数组。

这是解决方案:

// temporary array holds objects with position// and length of elementvar lengths = rivers.map(function (e, i) {    return {index: i, value: e.length };});
// sorting the lengths array containing the lengths of// river nameslengths.sort(function (a, b) { return +(a.value > b.value) || +(a.value === b.value) - 1;});
// copy element back to the arrayvar sortedRivers = lengths.map(function (e) { return rivers[e.index];});
console.log(sortedRivers);

输出:

[ 'Nile', 'Congo', 'Amazon', 'Rio-Grande', 'Mississippi' ]

在本教程中,我们学习了如何使用 JavaScript Array sort()方法对字符串、数字、日期和对象数组进行排序。

今天的内容就到这里了。

如果您还想学习更多关于数组的内容,请点击下文链接进行学习。

【JavaScript 教程】第六章 数组09— some() :检查数组中是否至少有一个元素通过了测试

【JavaScript 教程】第六章 数组08— every() :检查数组中的每个元素是否都通过了测试

【JavaScript 教程】第六章 数组07— index() :在数组中定位一个元素

【JavaScript 教程】第六章 数组06— slice() :复制数组元素

【JavaScript 教程】第六章 数组05— splice():删除、插入和替换

【JavaScript 教程】第六章 数组04— JavaScript 队列

【JavaScript 教程】第六章 数组03— Stack :使用 Array 的push()和pop()方法实现堆栈数据结构

【JavaScript 教程】第六章 数组02— Array Length:如何有效地使用数组的长度属性

【JavaScript 教程】第六章 数组01— 介绍JavaScript中的Array类型


学习更多技能

请点击下方公众号

浏览 37
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报