Update
此项目已经抽离出来,做成两个npm包:arr-sort, arr-del。功能增强,支持nested对象属性并支持传入比较函数功能。
一、问题背景
前端时间做项目遇到个数组多重筛选条件排序的问题,做的是一个展示用户拥有的红包和加息券页面,但是排序类似于下面这样:
- 先按照截止时间倒序排;
- 若截止时间一样,则按照获得时间倒序排;
- 若获得时间一样时,红包>加息券;
- 剩余则随机。
欢迎大家star学习交流:github地址
二、解决方法1
我就琢磨着,这个可以做成一个组件。但是实现的方法其实也就是算法有好多种,我当时最先想到的是数组的自带排序方法sort,在参数function里边去处理排序,确实是可以做到先按照截止时间排序,并且可以提取出截止时间相同的元素组成的数组,但是再这样递归下去直到最后一个条件,然后再归纳数组合并,数据不太好处理,也不容易做成函数的递归。我捉摸着写出了下面的代码:
|
|
三、解决方法2
不知道你们乱不乱啊,反正我是放弃了。。。既然这个走不通,我就想,我们能不能遍历所有条件一次选出一个或者几个元素,然后再从头遍历。就是说我们先从所有数组中选出截止时间离我们最近,如果只有一个,直接return,此次循环结束;如果有多个,再从中选出获得时间离我们最近的,如果只有一个,直接return,此次循环结束;如果有多个。。。一直到最后条件c后,return所有剩下的。这样第一轮就算结束了,然后我们将第一轮筛选出来的元素push进outArr里边,并从输入数组inArr中删除这些数组。接着再这样递归下去,直到inArr为空数组。
这样思路是不是清爽多了?也比较好处理递归的问题。废话少说,附上代码如下:
去除了原来用jquery的$.each()
方法遍历数组,改用for循环,解除依赖。这样脚本就是纯原生js写的,没有兼容性问题并且不依赖任何组件,大家放心使用。这里是用的AMD异步模块方案做的组件,没有依赖,输出一个对象,有delArrByIndex、maxObjArr、minObjArr和multiSortArr四个数组方法。
四、详细用法说明及测试
1、多重数组筛选方法:multiSortArr
针对类似如下的情况:
1. 先按照截止时间倒序排;
2. 若截止时间一样,则按照获得时间倒序排;
3. 若获得时间一样时,红包>加息券;
4. 剩余则随机。
for test
|
|
2、删除数组指定项(index)方法:delArrByIndex
for test
|
|
3、选出对象数组某个属性值最大、最小的对象组成的数组方法:maxObjArr、minObjArr
for test
|
|
五、总结
对比上面两种算法的实现,我个人觉得第一种,算法效率更高,因为一次原生数组排序方法就排查出所有第一个条件参数不一样的元素,如果此时没有重复的直接就return了。就算有重复的,后面也就是针对这些重复的进行排查,计算量也是比较小的。但是难就难在数据的存储方式,递归的实现以及最后数据的重组上,同时也比较耗内存,因为需要创建很多数组和对象(如果有比较多重复的话)。第二种,思路比较简单,实现起来方便。但是算法效率并不高,因为是相当于n + (n-1) + (n-2) + ... + 1 = 1/2*n(n+1)
复杂度,这里就不算n里边还要循环的次数,因为都这个都一样。而第一种看概率,如果没有重复的就直接是1次,重复多了也是比第二种复杂度小。第二种比较耗cpu,因为计算次数多。
经过测试目前没有发现问题,欢迎大家使用反馈~