在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,轉載請註明出處