在JavaScript中,Array对象的sort()方法是用来排序的,可是这个方法在默认状况下可能不是咱们想要的,好比对于以下数组数组
var arr = [2,5,10,20,7,15];
使用sort排序会获得以下结果:
[10, 15, 2, 20, 5, 7]函数
在不传递参数的状况下,它是按字符的Unicode编码来排序的。编码
为了解决这个问题,能够为sort()方法传递一个参数,这个参数ECMAScript是这么定义的:prototype
/** @param {function} [compareFn] @return {Array.<T>} */ Array.prototype.sort = function(compareFn) {};
参数为一个function,具体叫比较函数。咱们能够改写为以下形式,传递一个比较函数:code
arr.sort(function(a,b){ return a - b; });
a和b便是要比较的两个数,其返回值以下:对象
若 a 小于 b,在排序后的数组中 a 应该出如今 b 以前,则返回一个小于 0 的值。排序
若 a 等于 b,则返回 0。ip
若 a 大于 b,则返回一个大于 0 的值。字符串
对于返回值的三种结果,咱们能够直接使用“a-b”,这样就能够正确获得结果
[2, 5, 7, 10, 15, 20]get
那么,接下来咱们就来模拟一下这个方法和比较函数的实现。
首先,若是咱们不用这个方法,而是本身实现排序,那么咱们可使用传统的冒泡排序方法:
function sort(array){ for(var i=0; i<array.length - 1; i++){ // 假设数组已经排好序了 var isSorted = true; for(var j=0; j<array.length - 1 - i; j++){ if(array[j] > array[j + 1]){ var temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; // 还有比较,说明排序还未结束 isSorted = false; } } // 若是排序已经完成,跳出循环 if(isSorted){ break; } } }
这是一个循环次数最少的排序方法,可是,这个排序的适应性不强,对于字符串数组就不行了,假设有以下字符串数组,要求按字符串个数排序该如何实现?
var arry = ["aaa","aa","c","bb"."xxxxxxxx"];
这样的数组咱们不得不从新写一个方法来对字符串数组进行排序,须要改动上面冒泡排序的第6行的判断条件:
if(array[j].length > array[j+1].length){}
那么,既然只须要改动这一句,咱们能够把这一句做为参数传递,之后想怎么排就传什么样的参数,这个参数就是一个函数,回调函数。下面从新改写上面的冒泡排序,传递一个回调函数。
// 模拟sort() function sort(array,fn){ for(var i=0; i<array.length - 1; i++){ var isSorted = true; for(var j=0; j<array.length - 1 - i; j++){ if(fn(array[j], array[j + 1]) > 0){ var temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; isSorted = false; } } } if(isSorted){ break; } } }
注意第2行和第6行,给sort传递了一个fn参数,这是一个函数,而后在第6行调用,array[j]和array[j+1]分别就是回调函数的a,b两个比较值。用这个改写的方法便可对数值数组排序也能够对字符串数组排序了。
var arr = ["aaa","a","xxxxxx","abcd","ab"]; sort(arr, function (a,b) { return a.length - b.length; }); console.log(arr);
输出:["a", "ab", "aaa", "abcd", "xxxxxx"]
文章首发于读你博客,原文连接http://www.mybry.com/?p=594,转载请注明出处