2016-12-11 116 views
4

我發現使用沒有比較函數的排序會導致錯誤的答案,我不知道原因。Javascript Array.prototype.sort()錯誤,沒有比較功能

var a = [823564440,115438165,784484492,74243042,114807987,137522503,441282327,16531729,823378840,143542612] 

a.sort() 
a.sort((a,b) => a-b) 

這兩個應該在我的腦海中給出相同的結果,但他們沒有。顯然後者是正確的。

a.sort() 
[114807987, 115438165, 137522503, 143542612, 16531729, 441282327, 74243042, 784484492, 823378840, 823564440] 
a.sort((a, b) => a-b) 
[16531729, 74243042, 114807987, 115438165, 137522503, 143542612, 441282327, 784484492, 823378840, 823564440] 

有誰能告訴我背後的原因嗎?

+4

從[documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort):*默認的排序順序是根據字符串的Unicode代碼點。* – Li357

+1

首先將項目比作字符串。 – zerkms

+0

字符串排序與數字排序。 –

回答

5

MDN documentation

sort()方法排序的陣列的代替元素並返回數組。排序不一定穩定。 默認的排序順序是根據字符串Unicode代碼點。(Emphasis mine)†

由於您沒有提供函數,因此使用默認排序順序。因此,這些元素按照字符串進行排序,而後者則根據數字值排序。

因此,1之前2,2之前3等無論數字的位數作爲字符串比較的地方。 (請參見list of unicode characters;因爲Unicode中的1是U + 0031,所以它在U + 0032之前,因此更小)。

在你的例子中,這意味着115438165之前74243042雖然後者是數學上較小。因爲字符串被地方比較所以17比較不到,從而得到了結果。有關進一步閱讀,請參閱lexicographical order


†這是通過規範。請參閱ECMAScript® 2015 Language Specification,第22.1.3.24.1節 - 運行時語義:SortCompare(x, y)。這裏解釋瞭如果沒有通過排序功能,則比較xy(使用ToString找到)的字符串表示。

+1

謝謝!數值陣列這樣做很奇怪。 –

+0

@xgwang這樣做可能看起來很奇怪,但是(我相信)邏輯原因是因爲數組可以容納任何東西 - 不僅僅是數字。如果沒有排序函數傳遞並且您有一個非數字對象數組會怎麼樣?它不是按數字排序,而是根據字符串表示進行排序。 – Li357