2013-02-17 46 views
4

我無法理解爲什麼以下函數將數字排序爲字符串(在代碼的第三部分中)。瞭解Javascript.sort參數

var myArray = [10, 44, 32, 100, 0, 44, 3, 4]; 
console.log(myArray.toString()); // 10, 44, 32, 100, 0, 44, 3, 4 --> unsorted 

myArray.sort(); 
console.log(myArray.toString()); // 0,10,100,3,32,4,44,44 --> sorted like strings 

// this is what confuses me: 
myArray.sort(function (a, b) { 
return a - b; 
}); 
console.log(myArray.toString()); // 0,3,4,10,32,44,44,100 --> sorted numerically 

具體

  1. 如何ab得到填充?

  2. 爲什麼減去a - b按數字順序排序數字?

  3. 如果函數一次只檢查2個數字,所有數字如何按正確順序排序? (即ab

+2

的可能重複[真正發生在Javascript排序(http://stackoverflow.com/questions/8588921/what-really-happens-in-javascript-sort) – 2013-02-17 23:11:19

回答

6

.sort需要一個可選參數,它應該是一個函數。

.sort然後重複調用該函數,從該數組中傳遞一對值(參數ab)。然後,該函數返回一個被解釋像這樣一個值:

  • 如果返回的值小於0,則a < b
  • 如果返回值大於0,則a > b
  • 如果返回值正是0,然後a == b

利用這一點,.sort數字出使用任何排序算法的瀏覽器已經被編程爲使用項目的順序。

如果沒有排序功能,.sort會將項目排序爲字符串 - 這只是設計的一個任意點。理想情況下,您應該傳遞一個函數,以便在需要.sort的情況下使用,就像這裏函數強制將值作爲數字進行比較一樣。

+1

它怎麼知道何時停止?它是否將每個數字與每個其他數字進行比較? – jon 2013-02-17 23:16:22

+1

@jon您可能想了解[排序算法](http://en.wikipedia.org/wiki/Sorting_algorithm)是如何工作的。 – 2013-02-17 23:17:13

0

中的JavaScript .sort()函數總是排序陣列彷彿他們的含量分別爲字符串,默認情況下。這正是它所做的。基本上,默認排序功能對每個值執行.toString()

Here's a link to the specification.這很令人困惑,但關鍵在於對排序比較過程的描述結束。

+0

但爲什麼第二部分工作讓它按數字排序 - 即它是如何工作的? – jon 2013-02-17 23:13:51

+0

@Jon因爲你的函數將參數看作是數字而不是字符串。關鍵是你在做減法。 – Pointy 2013-02-17 23:17:26

3

無論出於何種原因(我應該查找文檔),Array.prototype.sort的默認行爲是按字符串排序,而不是數字排序。這意味着你必須定義數字排序行爲。

  1. 如何ab獲取填充 - 歡迎函數式編程的世界。數組在內部迭代,回調函數用(第一個元素)和b(第二個元素)調用,直到元素耗盡。你不必擔心太多,只要知道發生了什麼。幸運的是,documentation這個很清楚。如果回調的返回值小於0,則a的索引比b低。如果返回0,請將它們保持在與其他元素相同的索引處。如果返回正值,則b的索引低於a。這意味着a - b保證可以正確地進行數字排序。 但是,如果有任何非數字元素,您將遇到此回調函數的問題。只有在知道數組僅包含數字元素的情況下才使用它。

  2. 這是做一個簡單的插入排序,實際上並不一次兩個,但會回溯,如果b碰巧小於a。您可以通過向排序回調方法添加console.log(a,b)來檢查此行爲。

+0

我知道'.sort()'方法是插入排序而不是快速排序(最有可能)或合併排序(不太可能,但它可能會更好),我會*非常驚訝地發現。 – Pointy 2013-02-17 23:19:47

+0

我試着把'console.log(a,b)'放在函數裏面,它沒有工作......我真的很希望看到它通過問題一步步工作。我做錯了什麼:https://gist.github.com/jonamar/4974057? – jon 2013-02-17 23:21:48

+1

@jon思考'return'的作用。它突破了功能的權利。如果你調用'return'和*然後*'console.log',後者將永遠達不到,對嗎?在'return'之前放置'console.log'。 – 2013-02-17 23:23:26