一文说透前端排序 Array.protype.sort

1,673 阅读3分钟

前言

后端常常会返回一大串的数据,一般都是后端进行排序的,但是遇到一些特殊情况,也是会需要前端进行排序

后端:这个表单你排序下序哈~ 
前端:后端获取数据的时候直接排一下就可以啦 
后端:我看后台都是自己排序的呀 
前端:哪个后台 
后端:就是那几个使用 element-ui 、antd 的 table 组件,你难道不会吧?
···

好好好,排序是吧,我排(只是个乐子哈

排序

在学习算法的时候,有很多的的排序方法,如下

  • 冒泡排序
  • 选择排序
  • 插入排序
  • 归并排序
  • 快速排序

等等一系列的排序,这里给大家推荐一个链接里面详细说明了一些排序,感兴趣的可以看一下 visualgo.net/zh/sorting

QQ_1722666667031.png

我们已经过了那个刀耕火种的年代了,如果是对性能没有极致的要求,我们一般会使用 js 中数组的方法 sort 来进行排序

Array.protype.Sort 用法

sort 这个方法是对数组的元素进行排序,注意,这个方法会改变原数组。这个方法接收一个函数参数,返回值为两项数据比较的结果。如果省略这个函数,数组元素就会被转换为字符串,然后根据每个字符的 Unicode 码进行排序

基础用法

[1,4,5,1,3].sort() 
// [1, 1, 3, 4, 5] 
[1,4,5,1000,3].sort() 
// [1, 1000, 3, 4, 5]

[1,4,5,1000,3] 的比较中,1000排在了第二个,这是因为默认情况下,会把数组元素转换为字符串,然后根据每个字符串的 Unicode 码值进行排序,其实也就是字符串的比较

'3' > '1000' // true

进阶用法

那我们如何对这个排序做修正呢,我们需要添加一个函数参数

[1,4,5,1,3].sort((a,b)=> a - b) 
// [1, 1, 3, 4, 5]

我们来解释一下这个函数

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

a 代表第一个比较的数,b代表第二个比较的数,如果 返回的结果 > 0 ,那么把 a 排在 b 的后面。如果返回的结果 < 0, 那么把 a 排在 b 的前面。我们可以模拟一下这个过程,我们将 a 和 b 打印出来,看看都是谁和谁比较

[1,4,5,1,3].sort((a,b)=> {
   console.log(a,b)
   return a - b
})
/**
4 1
5 4
1 5
1 4
1 1
3 4
3 1
*/

用一张表格表示

a 值b 值a - b 值数组
413 >0 所以 a 排在 b 后面14
541 > 0 所以 a 排在 b 后面145
15-4 < 0所以 a 排在 b 前面1145
14-3 <0 所以 a 排在 b 前面
110 === 0 所以 a,b 位置不用动
34-1 <0 所以 a 排在 b 前面11345
312 > 0 所以 a 排在 b 前面

我们查看 V8 可以看到,如果是 长度小于 10 的话是插入排序

github.com/v8/v8/blob/…

没有了解过插入排序的可以了解下

这边简单解释一下,其实就是最开始是1,然后插入一个4和1比较,然后插入5和1,4分别比较,然后再插入1和1,4,5再比较。每一次调用都是一次比较的过程。

注意点

  • 如果数组中有 undefined,undefined 会被排到最后
  • 这个方法不适用于字符串
  • 这个方法会更改原始数组,如果希望不改变原始数组,可以使用 toSorted 方法

其他

我们来看看 element-ui 这个框架的 table 组件是怎么实现 sortable 的

image.png

同样也是通过一个方法来实现的,底层用的也是 sort

image.png