javascript 数组多重排序

488 阅读1分钟

背景

今天看到一个新来同事对数组多重排序写的算法,写的有点丑,性能也不太好。重新写了下,顺便整理下给新童鞋讲解的思路,适合没什么算法基础的同学看。 例子大概是这样的:
要求按照top(boolean), content(string, 是否为空), timestamp(number desc)进行先后排序,三级排序

let array = [
  {
    top: false,
    timestamp: 123,
    content: 'vb'
  },
  {
    top: true,
    timestamp: 1234,
    content: ''
  },
  {
    top: false,
    timestamp: 120,
    content: 'fool'
  }
]

方案

先说解决方案:

array.sort((pre, next) => {
  if(pre.top === next.top) {
    if(pre.content && pre.content) {
      return next.timestamp - pre.timestamp
    } else {
      return pre.content ? -1 : 1
    }
  } else {
    return pre.top ? -1 : 1
  }
})

大部分情况下,我们都会直接想到通过 Arrray.prototype.sort(compareFn) 进行排序, 但 compareFn 并不是那么好理解,有两个地方需要自己多练习和理解下:
一、返回值的意义;
1、return 0; pre和next位置不变;
2、return -1(小于0); 顺序调整为 pre -> next;
3、return 1(大于0); 顺序调整为 next -> pre;
二、desc or asc;
根据desc or asc 来处理返回值;

sort

虽然已经了解 Array.prototype.sort 方法的使用,但面试的时候呢?哈哈哈,因为排序算法很多,相关文章很多这里就不展开了。
因为是参考 Array.prototype.sort 来实现,按照它的特性前一个值和后一个值进行排序,可能是使用的冒泡排序,所以本文使用冒泡排序来写一段伪代码实现:

Object.defineProperty(Array.prototype, 'mySort', {
    value: function(compareFn) { 
        for(let i = 0, len = this.length; i < len; i += 1) {
          for(let j = i + 1; j < len; j += 1) {
            if(compareFn(this[i], this[j]) !== 0) {
              let temp = this[i]

              this[i] = this[j]
              this[j] = temp
            }
          }
        }
        return this
     }
})

后面了解了下,Array.prototype.sort 在不同浏览器使用的排序算法不一样,v8 在长度 <= 10时,使用插入排序,长度 > 10使用的快速排序,暂时不再拓展了。