【JavaScript 教程】第六章 数组10— sort() : 对数组中的元素进行排序
共 6416字,需浏览 13分钟
·
2022-01-20 01:28
英文 | https://www.javascripttutorial.net/
译文 | 杨小爱
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 cases
let 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 order
scores.sort((a, b) => a - b);
console.log(scores);
输出:
[ 5, 9, 10, 20, 70, 80 ]
要以降序对数字数组进行排序,您只需要反转比较函数中的逻辑,如下例所示:
let scores = [
9, 80, 10, 20, 5, 70
];
// descending order
scores.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 salary
employees.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 对象,然后比较两个日期,这与比较两个数字相同。
这是解决方案:
代码语言:JavaScript ( javascript )employees.sort(function (x, y) {
let a = new Date(x.hireDate),
b = new Date(y.hireDate);
return a - b;
});
console.table(employees);
优化 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 Nile
Congo Amazon
Congo Amazon
Congo Nile
Mississippi Congo
Mississippi Amazon
Amazon
Mississippi
它们怎么运行的:
首先,声明一个由著名河流名称组成的数组 rivers。
其次,使用 sort() 方法按其元素的长度对rivers数组进行排序。每当 sort() 方法调用比较函数时,我们就会将 Rivers 数组的元素输出到 Web 控制台。
如上面的输出所示,每个元素都被评估了多次,例如亚马逊 4 次,刚果 2 次等。
如果数组元素的数量增加,则可能会降低性能。
您无法减少比较函数的执行次数。但是,您可以减少比较必须执行的工作。这种技术称为施瓦兹变换。
要实现这一点,请按照以下步骤操作:
首先,使用 map() 方法将实际值提取到临时数组中。
其次,使用已经评估(或转换)的元素对临时数组进行排序。
第三,遍历临时数组,得到一个顺序正确的数组。
这是解决方案:
// temporary array holds objects with position
// and length of element
var lengths = rivers.map(function (e, i) {
return {index: i, value: e.length };
});
// sorting the lengths array containing the lengths of
// river names
lengths.sort(function (a, b) {
return +(a.value > b.value) || +(a.value === b.value) - 1;
});
// copy element back to the array
var 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类型
学习更多技能
请点击下方公众号