My favorites | Sign in
v8
Project Home Downloads Wiki Issues Source Code Search
New issue   Search
for
  Advanced search   Search tips   Subscriptions
Issue 103: javascript Array.sort() bug
4 people starred this issue and may be notified of changes. Back to list
Status:  WorkingAsIntended
Owner:  olehouga...@gmail.com
Closed:  Oct 2008


Sign in to add a comment
 
Reported by chris.f....@gmail.com, Oct 2, 2008
try running 
["50", "60", "100"].sort(function(a,b) {return Number(a)>Number(b)})

in Chrome 0.2.149.30, it gives you ["60", "100", 50"]. Huh?

in Firefox 3.0, Safari 3.1 and IE7 it gives you ["50", "60", "100"] as 
expected.
Oct 2, 2008
Project Member #1 f...@chromium.org
(No comment was entered for this change.)
Owner: olehougaard
Oct 2, 2008
#2 lrn%chro...@gtempaccount.com
It is, sortof, expected behavior - in the sense that the behavior of sort with this 
comparison function is undefined.

A comparison function for sort, given arguments a and b, must return a positive 
number if a > b, a negative number if a < b, and zero if they are equal.
See "consistent comparison function", ECMA 262,3ed, section 15.4.4.11, which
also states:
"If  comparefn is not  undefined and is not a consistent comparison function for the 
elements of this array (see below), the behaviour of  sort is implementation-
defined."

This comparison function returns true or false. When converted to a number, true 
becomes 1 and false become 0. That is, if a <= b, the sort operation considers them
equal. The problem is that the function is not symmetric: The arguments (50,60) 
returns false, which is interpreted as 50 being equal to 60, but passed as (60,50) it 
returns true, meaning that 60 > 50.

I.e., it's a coincidence that it works anywhere (except perhaps Firefox, which does 
seem to work consistently). The comparison function is not satisfying the contract 
expected by the sort function, so whether it works or not depends entirely on the 
order of arguments that the sort routing gives to the comparison.

This example only appears to work in IE, because the initial array is already sorted. 
If you start out with an unsorted array, it doesn't sort at all:
 ["100", "50", "60"].sort(function(a,b) {return Number(a)>Number(b)})
yields [100,50,60] in IE. Opera does the same. Firefox *does* sort, though.

For a better comparison function, try:
  function cmp(a,b) { return a == b ? 0 : a < b ? -1 : 1; }
  function numberCmp(a,b) { return cmp(Number(a),Number(b)); }


Oct 2, 2008
#3 lrn%chro...@gtempaccount.com
(No comment was entered for this change.)
Status: WorkingAsIntended
Sign in to add a comment

Powered by Google Project Hosting