JavaScript解惑记之Array.prototype.sort()

前言

看JS红宝书的5.2.5章节关于sort()方法,如何用一个compare函数,让数组顺序,倒序,有点云里雾里的。在网上度娘了一下,发现更迷糊了。走投无路的情况下,只能发动神技能,去 stackoverflow 上碰碰运气,本人的英语一直是处于被他人嘲笑的水平,所幸 stackoverflow 上的大牛们解释得通俗易懂,就连我这种渣渣也是豁然开朗。
附上原链接,造福更多的小伙伴:

Algorithm of JavaScript “sort()” Function

sort()的排序机制

首先,从一个案例讲起,假设我有一个数组:

var nums  = [10, 5, 40, 25, 100, 1];

然后将其排序:

console.log(nums.sort());
//得出的结果:[1, 10, 100, 25, 40, 5]

只是单纯的用 sort() 方法排序,得出的结果和我们想象的有点出入,这是因为 sort() 会把我们数组里面的数字全部转化成字符串。也就是说,在排序的时候,所排序的数组其实是:

var nums  = ["10", "5", "40", "25", "100", "1"];

如果我们把数字字符串用字母来替换,会怎样呢?

//0=>a
//1=>b
//2=>c
//4=>d
//5=>e
//转换前的数组
var nums = ["ba" ,"e" , "da" ,"ce" ,"baa","b"];
//得出的结果数组
// [1, 10, 100, 25, 40, 5]
// 将结果数组的数字转换成字符串,得到:
["b", "ba", "baa", "ce", "da","e"]

看到这里,感觉豁然开朗了,这不就是字典序排序嘛。

排序数字的方法

了解了 sort() 方法的排序机制,但是在实际开发中,我们一般不用这种类型的排序顺序,而红宝书中所谓的compare函数又是怎样一种存在呢?

function sortAsc(current, next){
	return current - next;
}
function sortDesc(current, next){
	return next - current;
}

sort() 方法接受一个比较函数,元素两两比较,当返回的结果是0或者负数时,元素的位置不变,当返回的结果为正数时,前后两个元素交换位置。

//剖析执行过程
console.log(nums.sort(sortAsc));	//[1, 5, 10, 25, 40, 100]
//原数组:[10, 5, 40, 25, 100, 1];
//1:[5, 10, 25, 40, 1, 100];
//2:[5, 10, 25, 1, 40, 100];
//3:[5, 10, 1, 25, 40, 100];
//4:[5, 1, 10, 25, 40, 100];
//5:[1, 5, 10, 25, 40, 100];
//==================================================//
console.log(nums.sort(sortDesc)); //[100, 40, 25, 10, 5, 1]
//原数组:[10, 5, 40, 25, 100, 1];
//1:[10,40 ,25,  100, 5, 1];
//2:[40, 25, 100, 10, 5, 1];
//3:[40, 100, 25, 10, 5, 1];
//4:[100, 40, 25, 10, 5, 1];

排序扩展

照这个两两比较,正数交换位置,负数及0元素位置不变的“哲学”,我们可以写出不同数据类型的不同排序方法:

数组排序
order (1, 2, 3...):

function(a, b){
    return a - b;
}

order (9, 8, 7...):

function(a, b){
    return b - a;
}

排序字符串
order (A, B, C...):

function(a, b){
    return a > b? 1: -1;
}

order (Z, Y, X...):

function(a, b){
    return b > a? 1: -1;
}

通过对象属性来排序
sort by key:

function(a, b){
    return a.key - b.key;
}
posted @ 2016-08-07 00:09  走在全栈的路上  阅读(177)  评论(0)    收藏  举报