js数组给我们提供了很多非常有用的方法,可以让我们的代码更简洁。其中之一就是它的排序方法Array.prototype.sort
。什么冒泡排序,快速排序……这些排序算法还能记得多少?反正我是基本不用了。排序我就认sort。请看下面这个排序逻辑
1 | users.sort((a, b) => { |
问题
上面代码的排序规则是先按姓名升序排列,姓名相同的按年龄升序排列。可是你能一眼就看出来这个排序规则么。在你每次去写排序的时候,是否有纠结应该返回1,还是-1。到底返回哪个值是升序,哪个是倒序呢。是不是随便写一个,如果发现顺序不对,把 1 和 -1 换一下就好,也不是天天排序,懒的区分。那有没有一种更加简单的试呢,能够简洁明了的指定排序方式,有如 sql 语句那样
1 | SELECT * FROM user ORDER BY name ASC, age ASC |
新打开方式
这里借用 yatter 中的 sorter 方法来实现我们想要的功能
1 | import {sorter} from 'yatter'; |
是不是更加简单,更加易懂。sorter 第一个参数是函数,将需要排序的字段按先后顺序组成一个数据返回,第二个参数指定升序或者降序。如果多个字段排序方向不同,可以使用数组
1 | users.sort(sorter(a => [a.name, a.age], ['asc', 'desc'])); |
如此则是先按姓名升序,再按年龄降序排列
应用
上面例子都很简单,都是直接按某个字段比较排序就可以,如果需要综合多个字段,或者字段本身是没法排序的。就需要稍微处理一下了
按总分排序,总分相同按学号升序
1
users.sort(sorter(a => [a.ch + a.en + a.ma, a.id], ['asc', 'asc']));
将多科成绩加起来作为第一排序维度,学号作为第二排序维度
车牌排序
如果有一堆车牌,需要按城市排序(地级市),以江苏各城市为例,十三个地级市,车牌从 A 到 N。 另外苏州还多一个 U, 如此就不能简单按这个字母排序了,否则 U 会被排到最后。我们需要将苏U 和苏E 同等对待。假如数组中的对象的 city 字段保存的这些城市的字母编码1
arr.sort(sorter(a => [a.city === 'U' ? 'E' : a.city], 'asc'));
怎么样?这样的数组排序会不会更加简单一些。yatter 中还有很多其它的实用函数,用起来吧。