前言
后端常常会返回一大串的数据,一般都是后端进行排序的,但是遇到一些特殊情况,也是会需要前端进行排序
后端:这个表单你排序下序哈~
前端:后端获取数据的时候直接排一下就可以啦
后端:我看后台都是自己排序的呀
前端:哪个后台
后端:就是那几个使用 element-ui 、antd 的 table 组件,你难道不会吧?
···
好好好,排序是吧,我排(只是个乐子哈
排序
在学习算法的时候,有很多的的排序方法,如下
- 冒泡排序
- 选择排序
- 插入排序
- 归并排序
- 快速排序
等等一系列的排序,这里给大家推荐一个链接里面详细说明了一些排序,感兴趣的可以看一下 visualgo.net/zh/sorting
我们已经过了那个刀耕火种的年代了,如果是对性能没有极致的要求,我们一般会使用 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 值 | 数组 |
|---|---|---|---|
| 4 | 1 | 3 >0 所以 a 排在 b 后面 | 14 |
| 5 | 4 | 1 > 0 所以 a 排在 b 后面 | 145 |
| 1 | 5 | -4 < 0所以 a 排在 b 前面 | 1145 |
| 1 | 4 | -3 <0 所以 a 排在 b 前面 | |
| 1 | 1 | 0 === 0 所以 a,b 位置不用动 | |
| 3 | 4 | -1 <0 所以 a 排在 b 前面 | 11345 |
| 3 | 1 | 2 > 0 所以 a 排在 b 前面 |
我们查看 V8 可以看到,如果是 长度小于 10 的话是插入排序
没有了解过插入排序的可以了解下
这边简单解释一下,其实就是最开始是1,然后插入一个4和1比较,然后插入5和1,4分别比较,然后再插入1和1,4,5再比较。每一次调用都是一次比较的过程。
注意点
- 如果数组中有 undefined,undefined 会被排到最后
- 这个方法不适用于字符串
- 这个方法会更改原始数组,如果希望不改变原始数组,可以使用 toSorted 方法
其他
我们来看看 element-ui 这个框架的 table 组件是怎么实现 sortable 的
同样也是通过一个方法来实现的,底层用的也是 sort