前言
sort() 方法的官方定义是用于对数组的元素进行排序,但是为什么在作用于纯数字数组的时候排序的结果总是达不到预期效果呢?
关键点
sort() 方法中有一个参数,非必填,但是在忽略此参数的情况下,使用sort()排序会默认先调用数组中每一项元素的toString()方法,然后根据首字母的 ASCLL 码值的大小进行排序。
1、对 字符型 数组进行排序
var arr1=['a','b','A','B'];
arr1.sort();
console.log('arr1',arr1); //["A", "B", "a", "b"]
a的 ASCLL 码值为97,b的 ASCLL 码值为98 ,A的 ASCLL 码值为65,B的 ASCLL 码值为66,所以arr1经过sort排序后数组中元素顺序如上图所示。
此时使用sort()排序后的arr1中数组元素从小到大排列是没问题的,那么接下来让我们看一看在纯数字数组中使用sort()排序后的结果如何?
2、对 数字型 数组进行排序
var arr2=[12,5,28,2];
arr2.sort();
console.log('arr2',arr2); //[12, 2, 28, 5]
此时可以看到排序的结果并不是我们预想中的按 从小到大 的顺序排列,是由于 数字 0 的ASCLL码值为 16,数字 1 的ASCLL码值为17,依次类推……
那么问题来了,面对纯数字数组,难道官方给出的sort方法就无效了吗?答案当然是否定的,我们可以通过在sort方法的参数中传入一个函数来解决数字数组的排序问题。
// 对sort添加比较函数
function compareNum(x,y){
if(x<y){
return -1;
}else if(x==y){
return 0;
}else if(x>y){
return 1;
}
}
//再次调用sort()函数
arr2.sort(compareNum);
console.log('arr2 again',arr2); //[2, 5, 12, 28]
如上图所示,在sort()中传入了一个compareNum的函数,此时的结果就达到了我们的预期。
如果要实现一个数组的升序,降序排列,可以将比较函数简写如下:
//升序
arr.sortUp(function(x,y){
retun x-y;
});
//降序
arr.sortDown(function(x,y){
retun y-x;
});
拓展
如果要将一个数组中的元素乱序排列呢?同样的我们也可以借助于sort() 函数。将随机函数中的参数不做比较,每次随机生成一个0-1的数,与中介值0.5比较,此时返回的1和-1是随机的,同样也实现了数组元素的随机排列。
// 打乱数组(数组元素随机)
function randomSort(x,y){
return Math.random() > 0.5 ? 1 : -1;
}
var arr3 = [0,1,2,3,4,5,6,7,8,9];
arr3.sort(randomSort);
console.log('arr3',arr3)