在 JavaScript 中对整数数组进行排序
介绍可用于按特定顺序对数组进行排序的 .sort
方法,本教程的目的是解释为什么要正确排序整数数组时该方法需要比较函数。
此比较函数将指示排序顺序。此外,我们将解释如何使用它来进行降序排序,以及通过将比较函数用作 .sort
方法中的箭头函数的更短的方法来一起使用它们。
在 JavaScript 中使用 .sort
方法对整数数组进行排序
.sort
方法是 Array
实体的方法,它从最初调用此方法的数组中返回一个有序数组。例如:
// Input
let array = [10, 10000, 1000, 100, 1]
console.log(array.sort())
输出:
// Output
[ 1, 10, 100, 1000, 10000 ]
当然,这是预期的,因为 .sort
方法对数组进行排序。但是,如果我们有以下输入:
// Input
let array = [12900, 877, 12, 992, 10000]
console.log(array.sort())
我们有这样一个错误的顺序:
// Output
[ 10000, 12, 12900, 877, 992 ]
这是因为 .sort
默认顺序基于 UTF-16
或 16-bit Unit Transformation Format
,这是 Unicode 模式的编码。该方法将数组值转换为字符串类型,然后对它们的 Unicode 值进行排序。
有了这个解释,.sort
方法也可以用于对其他数据类型进行排序,而不仅仅是数字。
但是如何使用 .sort
方法对数组进行正确排序?很简单:使用比较函数。
将比较函数作为参数传递
由于 .sort
方法可以在没有任何参数的情况下使用,所以比较函数是可选的。基本上,这个函数定义了 .sort
方法的顺序,这个函数接收两个参数:第一个要比较的元素和第二个要比较的元素。
.sort
方法将:
- 如果
compareFunction
返回的值大于 0,则将first
放在second
之后; - 如果
compareFunction
返回的值小于 0,则将first
放在second
之前; - 如果
compareFunction
返回的值等于 0,则不执行任何操作。
因此,使用 compareFunction(first, second)
,我们可以通过在 first
和 second
参数之间传递操作来指定排序的顺序。按升序排列,
// Ascending ordering
function compareFunction(first, second){
if(first > second) return 1 // 1 is greater than 0, so .sort will put first after second.
if(first < second) return -1 // -1 is less than 0, so .sort will put first before second.
return 0
}
对于降序,我们可以反转运算符。
// Descending ordering
function compareFunction(first, second){
if(first < second) return 1 // 1 is greater than 0, so .sort will put first after second.
if(first > second) return -1 // -1 is less than 0, so .sort will put first before second.
return 0
}
现在,将用于升序排序的 compareFunction
与 .sort
方法放在一起,最后,我们有:
// Input:
let array = [12900, 877, 12, 992, 10000]
// Ascending
array.sort(function compareFunction(first, second){
if(first > second) return 1 // 1 is greater than 0, so .sort will put first before second.
if(first < second) return -1 // -1 is less than 0, so .sort will put first after second.
return 0
})
console.log(array)
输出:
// Output:
[ 12, 877, 992, 10000, 12900 ]
在 JavaScript 中使用箭头函数对整数数组进行排序
我们还可以使用箭头函数将所有代码块减少到最小的语法。
箭头函数是另一种使用语法较短的函数的方法。箭头函数是匿名函数,这意味着它们没有命名(存储在变量中或作为函数参数传递)并且不能在所有情况下使用。
通过箭头函数的结构,可以将传统函数转换为更短的块,例如:
// Common anonymous function
function (x){
return x + 1;
}
// Arrow function
(x) => x + 1
除此之外,箭头函数的结构可以自动返回表达式值而无需保留字 return
:
// Arrow function
let arrowFunction = (x) => x + 1
console.log(arrowFunction(1))
输出:
//Output
2
console.log()
打印 1 + 1
的值,即 2
,即使 arrowFunction
没有使用 return
语句。它将帮助我们进行下一步。
如前所述,.sort
方法中可以有一个比较函数,该函数可以是箭头函数。转换之前的比较函数结构,我们可以将所有代码块转换为更短的块,如下所示:
// Input:
let array = [10000, 10, 100, 1000, 1]
array.sort((first, second) => {
if(first > second) return 1
return -1
})
// Ascending: If first > second == true, then change one by the other.
console.log(array)
我们可以将条件删除为 first < second
,如果主要条件不是这种情况,则默认返回 -1
值;假设 .sort
方法的 0
值是相等的值,这样,它们可以在不影响最终结果的情况下改变它们的位置。这样,我们可以减少更多,如下例所示:
// Input:
let array = [10000, 10, 100, 1000, 1]
array.sort((first, second) => first > second ? 1 : -1)
// Ascending: If first > second == true, then change one by the other.
console.log(array)
看看之前的 >
比较和默认 return
已更改为仅一个比较:first > second ? 1 : -1
。这意味着如果比较为 true
,则返回 1
;如果不是,它返回 -1
。
我们需要 ?
三元运算符,因为 first > second
比较只会导致 true
或 false
。但如前所述,.sort
方法需要 1
、-1
或 0
。
输出:
// Output:
[ 1, 10, 100, 1000, 10000 ]
对于降序:
// Input:
let array = [10000, 10, 100, 1000, 1]
array.sort((first, second) => first < second ? 1 : -1)
// Descending: If first < second == true, then change one by the other.
console.log(array)
输出:
// Output:
[ 10000, 1000, 100, 10, 1 ]
另一种方法是使用 -
三元运算符进行减法。当我们使用 array.sort((first, second) => first > second ? 1 : -1)
时,如果 first - second
的结果大于 0,那么将是一个相互变化的索引。如果 first - second
的结果小于 0,则不会发生任何事情,对于相等的值,比较将返回 0
。
例子:
// Input:
let array = [10000, 10, 100, 1000, 1]
console.log(array.sort((first, second) => first - second))
输出:
// Output:
[ 1, 10, 100, 1000, 10000 ]
我们可以按降序做什么?不,它不会将 -
三元运算符更改为+
,因为每个正数加上另一个正数会导致值大于 0。但是我们有一个简单的解决方案:将 first - second
反转为 第二 - 第一
。
这样,如果 second - first
的结果大于 0,则 .sort 方法将彼此更改它们的位置。
例子:
// Input:
let array = [10000, 10, 100, 1000, 1]
console.log(array.sort((first, second) => second - first))
输出:
// Output:
[ 10000, 1000, 100, 10, 1 ]