背景
今天看到一个新来同事对数组多重排序写的算法,写的有点丑,性能也不太好。重新写了下,顺便整理下给新童鞋讲解的思路,适合没什么算法基础的同学看。
例子大概是这样的:
要求按照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使用的快速排序,暂时不再拓展了。