145

In multiple browsers, the following code doesn't sort the numbers correctly:

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

It returns 10,100,20,30,60.

Anyone know why?

ashleedawg
  • 20,365
  • 9
  • 72
  • 105
Some Guy
  • 15,854
  • 10
  • 58
  • 67
  • 2
    Just a late comment, if you do not implicitly pass a function then you are telling it to sort an array of unicodes/strings. in unicode 100 is less than 20. – Qaddura May 26 '16 at 10:52
  • The "reason why" is `Array.sort` sorts [**alphabetically**](https://en.wikipedia.org/wiki/Alphabetical_order), not numerically. For numeric sort: `a.sort(function(a,b){return a-b})`. – ashleedawg Feb 01 '22 at 00:00

5 Answers5

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

These can be confusing.... check this link out.

Joseph Marikle
  • 76,418
  • 17
  • 112
  • 129
  • 46
    In ES6 it's even more elegant: `a.sort((a, b) => a - b)` – veich Apr 19 '17 at 14:07
  • quiet elegant. I used the ES6Version of the same and works like a charm, and why this is not the answer???? – Rohith Sep 26 '19 at 16:06
  • 4
    @Rohith This answer was written when I had only just recently joined SO, and it's honestly not a very well written answer either. :P The solution is wonderful, but it doesn't explain why the issue occurs, so I think Jason's answer should definitely be the marked solution. I'm glad you found my answer useful, though! – Joseph Marikle Sep 26 '19 at 19:38
  • small note here -- generally speaking you never want to reuse variable names (even if they're block scoped). we're sorting an array called 'a' and then reusing 'a' to represent an array item. if this is confusing anyone 'a' is not the same value. to clarify: `array.sort((a, b) => a - b)` – unfollow Apr 11 '22 at 13:37
  • That's wrong when the question is "how to sort numbers correctly". It doesn't take NaNs into account, e.g. `[0, -1, 3.14, 0/0, -100, 10, 0.2]` – Stefnotch May 20 '23 at 18:46
81

I've tried different numbers, and it always acts as if the 0s aren't there and sorts the numbers correctly otherwise. Anyone know why?

You're getting a lexicographical sort (e.g. convert objects to strings, and sort them in dictionary order), which is the default sort behavior in 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.

In the ECMAscript specification (the normative reference for the generic Javascript), ECMA-262, 3rd ed., section 15.4.4.11, the default sort order is lexicographical, although they don't come out and say it, instead giving the steps for a conceptual sort function that calls the given compare function if necessary, otherwise comparing the arguments when converted to strings:

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.
Community
  • 1
  • 1
Jason S
  • 184,598
  • 164
  • 608
  • 970
35

The default sort for arrays in Javascript is an alphabetical search. If you want a numerical sort, try something like this:

var a = [ 1, 100, 50, 2, 5];
a.sort(function(a,b) { return a - b; });
Nick Husher
  • 1,909
  • 11
  • 13
19

You can use a sort function :

var myarray=[25, 8, 7, 41]
myarray.sort( function(a,b) { return a - b; } );
// 7 8 25 41

Look at http://www.javascriptkit.com/javatutors/arraysort.shtml

Julien Lafont
  • 7,869
  • 2
  • 32
  • 52
-6

try this:

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;
}
Samir Adel
  • 2,691
  • 2
  • 15
  • 16
  • check code here: http://jsfiddle.net/8yxtg/1/ – Samir Adel Aug 09 '11 at 18:26
  • 7
    First, `a > b ? false : true` can be simplified to `a < b`. Second, you actually need to return `-1`, `0` or `1` so this is not completely correct (although it might work fine). – pimvdb Aug 10 '11 at 09:40
  • 1
    The sort function should return -1, 0 or 1 (not true/false). Most implementations will actually accept , 0 or which is why `return a-b` usually works for numbers. – sstur Nov 22 '13 at 18:07
  • `code`return a - b`code` does not manage correctly negative numbers... a < b does. – Max Oct 26 '15 at 12:03
  • @Max uhh... it manages negative numbers just fine, try it. – semicolon Jun 06 '17 at 17:46
  • @pimvdb - a > b works fine on ios platform - but for android platform, a > b ? 1 : -1 was needed. Samir got downvoted - but his answer and your response helped me – ajitweb Aug 26 '20 at 09:50