多条件排序
有个这么个要求,给一组数组
var data = [{a:1,b:2},{a:2,b:5},{a:3,b:4},{a:2,b:7},{a:1,b:2},{a:2,b:7},{a:4,b:8},{a:2,b:123},{a:5,b:23},]
要求a从小到大排序,a相等的b从大到小排序
首先实现属性a从小到大排序
data.sort(function(a,b) {return a.a - b.a})
接着继续掉调用把属性a排序好的数组
data.sort(function(a,b) {return a.a - b.a}).sort(function(a,b) {// 如果a属性相等则进行比较,否则不改变位置if(a.a === b.a) {return b.b - a.b} else {return -1}})console.log(data)
打印一下,也没问题。本以为就这样能搞定的我,还是图样了。
当我把数组的元素增加多几个的时候:
var data = [{a:1,b:2},{a:2,b:5},{a:3,b:4},{a:2,b:7},{a:1,b:2},{a:2,b:7},{a:4,b:8},{a:2,b:123},{a:5,b:23},{a:1,b:23},{a:2,b:55},{a:4,b:8},{a:2,b:12},{a:5,b:33},]
问题就来了,使用上面的方法排序,完全得不到预想的结果。
这明明刚才还可以的怎么增加一点数据就完全变样了呢,所谓一言不合看源码。还真是有道理
v8 array部分源码 (搜索“InnerArraySort”)
可以看到该方法首行就备注了
// In-place QuickSort algorithm.// For short (length <= 10) arrays, insertion sort is used for efficiency.
V8 引擎 sort 函数只给出了两种排序 InsertionSort 和 QuickSort,数量小于10的数组使用 InsertionSort,比10大的数组则使用 QuickSort。
快排不像插入排序,从后往前扫相邻的两个元素进行比较,而是找基准,遍历数组,小于基准的放在left,大于基准的放在right,递归
修改后的方法
data.sort((a, b) => {return a.a === b.a ? ( a.b - b.b ) : a.a - b.a;})
封装一下
var by = function(name, minor){return function(o, p) {var a, b;a = o[name];b = p[name];if (a === b) {return typeof minor === 'function' ? minor(o,p) : 0;}if (typeof a === typeof b) {return a < b ? -1 : 1;}}}data.sort(by('age',by('sin')));
