如何使用Array.sort()正确地对数字进行排序?

147
在多个浏览器中,以下代码无法正确地对数字进行排序:
a = new Array();
a.push(10);
a.push(60);
a.push(20);
a.push(30);
a.push(100);
document.write(a.sort())
它返回 10,100,20,30,60。 有人知道为什么吗?

2
只是个晚评论,如果您没有明确传递一个函数,则是在告诉它对一组Unicode /字符串进行排序。在Unicode中,100小于20。 - Qaddura
“为什么”的原因是 Array.sort字母顺序排序,而不是按数字排序。要进行数字排序,请使用:a.sort(function(a,b){return a-b}) - ashleedawg
5个回答

177
a.sort(function(a,b){return a - b})

这可能会令人感到困惑....查看此链接


47
在ES6中,它甚至更加优雅:a.sort((a, b) => a - b) - veich
我使用了ES6版本的代码,它非常优雅,并且运行得非常好。为什么这不是答案呢? - Rohith
4
@Rohith 这个答案是我刚加入SO时写的,实际上它并不是一个非常好的答案。:P 解决方案很棒,但它并没有解释为什么会出现这个问题,所以我认为Jason的答案应该被标记为答案。不过,我很高兴你发现了我的答案有用! - Joseph Marikle
小提示:通常情况下,您不希望重复使用变量名称(即使它们是块作用域)。我们正在对名为“a”的数组进行排序,然后重新使用“a”表示数组项。如果这让任何人感到困惑,“a”不是相同的值。澄清一下:array.sort((a, b) => a - b) - unfollow
当问题是“如何正确排序数字”时,这是错误的。 它没有考虑NaN,例如[0,-1,3.14,0/0,-100,10,0.2] - Stefnotch

81

我尝试了不同的数字,它总是会像0不存在一样正确排序其他数字。有人知道为什么吗?

你得到的是字典排序(例如将对象转换为字符串,并按字典顺序进行排序),这是Javascript中默认的排序行为:

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort

array.sort([compareFunction])

Parameters

compareFunction

Specifies a function that defines the sort order. If omitted, the array is sorted lexicographically (in dictionary order) according to the string conversion of each element.

在ECMAscript规范(通用Javascript的规范参考)中,ECMA-262,第3版,第15.4.4.11节, 默认排序顺序是按字典顺序排列,尽管他们没有明确说明,而是给出了一个概念性排序函数的步骤,如果必要,调用给定的比较函数,否则将参数转换为字符串进行比较。
13. If the argument comparefn is undefined, go to step 16.
14. Call comparefn with arguments x and y.
15. Return Result(14).
16. Call ToString(x).
17. Call ToString(y).
18. If Result(16) < Result(17), return −1.
19. If Result(16) > Result(17), return 1.
20. Return +0.

@maxhud,如果你想发表什么,请添加你自己的答案。 - Jason S
这是面试时问我的问题..哈哈,我知道JS很奇怪!但我喜欢它,哈哈。 - minigeek

35

Javascript中数组的默认排序方式是按字母顺序排序。如果你想要按数字排序,可以尝试像这样:

var a = [ 1, 100, 50, 2, 5];
a.sort(function(a,b) { return a - b; });

19

13
这是a - b;它返回相反的顺序。 - pimvdb
1
按照 @pimvdb 的建议,请把答案更正为 a-b。 - Vasanth

-6

试试这个:

a = new Array();
a.push(10);
a.push(60);
a.push(20);
a.push(30);
a.push(100);
a.sort(Test)

document.write(a);


function Test(a,b)
{
    return a > b ? true : false;
}

请在此处检查代码:http://jsfiddle.net/8yxtg/1/ - Samir Adel
7
首先,a > b ? false : true 可以简化为 a < b。其次,实际上您需要返回 -101,因此这并不完全正确(尽管它可能正常工作)。 - pimvdb
1
排序函数应该返回-1、0或1(而不是true/false)。大多数实现实际上会接受<任何负数>、0或<任何正数>,这就是为什么return a-b通常适用于数字的原因。 - sstur
codereturn a - bcode不能正确处理负数,但是a < b可以。 - Max
@Max 嗯...它可以很好地处理负数,试试看。 - semicolon
@pimvdb - 在iOS平台上,a > b可以正常工作 - 但在Android平台上,需要使用a > b ? 1 : -1。Samir的回答被downvote了 - 但他的回答和你的回复都对我有所帮助。 - ajitweb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接