js中sort排序的用法和工作原理

我们可以用sort()方法对数组中的元素进行排序,一般有以下几种用法:

第一种是直接调用sort()方法,不提供任何参数,这时将采用默认排序,默认排序会先将数组中的元素先转换为字符串,然后按照字符编码的升序排列。

需要注意的是:转换会直接作用到原数组上,并不会创建一个转换后的新数组,且转换后数值的类型不会发生变化。

第二种是传入一个用于指定排序的函数,该函数接收两个参数,用这两个参数来映射数组中“每两个需要排序的元素”,并在函数体中定义排序条件,通过返回值来确定顺序。

例如:

function(a, b) { return 1 }

这个函数有ab两个参数,分别映射数组中“每两个需要排序的元素(从右至左:第一个元素作为参数a,第二个元素作为参数b)”;

函数体返回一个数值,这个数值用于确定a元素相对b元素的位置(或者说b元素相对a元素的位置):

当返回值大于0时,表示把a元素排到b元素后面;

当返回值小于0时,表示把a元素排到b元素前面;

当返回值等于0时,表示两个元素的位置不变;

先举最简单的例子:

对只有两个元素的数组[1, 2]进行排序,排序函数中的参数ab分别对应21,如果搞不清楚参数的对应关系,可以用console.log()方法输出查看:

当函数体返回1时(1>0),会把a排到b的后面,结果仍然是[1, 2]

而当函数体返回一个小于0的数值时,就会把a元素排到b元素的前面,返回[2, 1]

上面的例子虽然简单,但是并不常用,因为它针对任意两个元素都返回相同的数值,排序逻辑也都是一样的,导致排序后的结果要么和原顺序相同,要么是翻转元素顺序(和reverse()方法效果相同)。

在实际应用中,我们更多会使用灵活的条件语句来判断返回值,例如:

上例中通过传入排序函数使数组内元素按照升序排列,我们来看一下这个排序函数:

function(a, b) { return a > b ? 1 : -1 }

函数体中的语句通过比较a元素和b元素来确定返回值,a>b时返回1,其他情况返回-1(返回值可以是任意数字,不一定非要是1-1),返回值用于确定a元素相对b元素的位置。

为了完成对数组的排序,需要每次选取两个元素进行对比,然后不断迭代,直到完成对所有元素的排序,举例来说:

传入13,那么从右至左,第一个数字传入aa=3,第二个数字传入bb=1,接着进入条件语句,由于a>b,所以返回11>0),把a元素排到b元素的后面,排序后的结果是1, 3

传入54,那么从右至左,第一个数字传入aa=4,第二个数字传入bb=5,接着进入条件语句,由于a<b,所以返回-1-1<0),把a元素排到b元素的前面,排序后的结果是4, 5

……

最终数组[1, 3, 2, 5, 4]排序后的结果是[1, 2, 3, 4, 5](升序)。

有一种简单的排序函数写法同样可以实现升序排列:

function(a, b) { return a - b }

这样在a>b时,函数会返回一个大于0的值,a元素会排在b元素的后面;

a<b时,函数会返回一个小于0的值,a元素会排在b元素的前面;

a=0时,函数会返回一个等于0的值,a元素和b元素的位置不变。

效果如下:

两种升序排列函数只需稍加调整下就可以变为降序排列函数: