sort, toSorted
撰写时间:2024-03-11
最新修订:2024-03-11
sort, toSorted
对数组排序。
- sort直接在原数组上排序。
- toSorted在原数组的一个副本上排序。原数组不受排序的影响。
原型
- FunctioncompareFn
- FunctioncompareFn
参数
- callbackFn
-
回调函数。该回调函数接受2个参数。其原型如下:
numbercompareFn- *a
- *b
- a
- 定义排序规则的第一个元素。
- b
- 定义排序规则的第二个元素。
回调函数compareFn期待一个返回值。这个返回值将作为
a - b
的结果来决定排列次序。因此:- 如果返回值小于0,则
a - b < 0
, 则a < b
。因此a将排在b的前面。 - 如果返回值等于0,则
a - b = 0
, 则a = b
。因此a与b的排列次序一样。则两者在数组中的位置保持不变。 - 如果返回值大于0,则
a - b > 0
, 则a > b
。因此a将排在b的后面。
返回值
sort返回经排序后的原数组的引用。
toSorted在原数组的一个副本上进行排序,返回该新数组。
说明
sort方法对数组进行原地排序,因此原来的数组变成经排序的数组。该方法的所返回的数组是原数组的引用。
toSorted在原数组的一个副本上进行排序,原数组未受排序影响。该方法所返回的数组是经排序后的新数组。
如果参数未指定回调函数,则将所有参与排序的数组元素都转换为字符串后再进行排序。具体详见下面的例子。
例子
原地排序
上面,NumUtils的静态方法GetIntsInRange返回一个元素数量为5、数值范围为 [1, 100] 的数组。
调用sort方法进行排序后,默认情况下对数组从小到大排序。
排序后,原来的数组也得以发生变化,所返回的数组是原来数组的引用。
在副本上进行排序
调用toSorted方法进行排序,该方法返回已经排序的新数组,但原数组未受影响。
指定排序规则
默认情况下,sort方法是将回调函数返回值作为a - b
的结果来决定排列次序,因此这是升序排序。如果我们要改为降序,则只需在回调函数中返回b - a
的结果即可。
在决定回调函数中到底是使用a - b
还是使用b - a
时,我们可以总结为一句话:视 a 为小数,b 为大数;被减数将排在左边。
因此如果我们希望升序排列,则将小数a
作为被减数;如果希望降序排列,则将大数b
作为被减数。
数组元素为对象时的排序
对于下面的数组:
每个数组元素均为具体的对象。而对这种具体的对象,没有默认的排序规则。我们即可对其name属性进行排序,也可根据其num属性来进行排序。这完全由用户自行决定。
下面,我们对num属性进行降序排序:
取num属性参与比较运算。既然是降序,我们就将大数作为被减数。结果为:
排序的默认行为
对于下面的数组:
使用默认的升序排序。您认为结果是什么?既然是升序,结果当然是[89, 150]
。但我们错了。
原因在于,这个世界太丰富多彩了,参与排序远不止只有整数而已。伟大且如爱因斯坦,尚不能统一宇宙4种之力。但雷人JavaScript却可以。在我们未指定回调函数时,它将所有参与排序的元素都统一转换为字符串,然后再根据字符串的UTF-16的码位值来进行排序。
上面,即使数组的两个元素均为整数,但经转换为字符串后,就成了["89", "150"]
,然后就开始逐字符比较了,"8"
与"1"
相比较,您认为哪个应排在先?
而更狠的是,在排序结果出来后,如果我们对结果产生质疑,欲查看结果数组中的数据类型时:
我们总是一次又一次地上当受骗。
因此,在调用sort方法时,我们应尽可能提供回调函数,以防止JavaScript擅自将数据类型悄悄转换为字符串来排序。