Bug 37123 - Sorting array of objects fails.
Summary: Sorting array of objects fails.
Status: RESOLVED INVALID
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: Mac (Intel) OS X 10.6
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-04-05 16:05 PDT by Berry Kercheval
Modified: 2010-04-05 16:25 PDT (History)
2 users (show)

See Also:


Attachments
Test case as an html file (533 bytes, text/html)
2010-04-05 16:25 PDT, Oliver Hunt
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Berry Kercheval 2010-04-05 16:05:04 PDT
Debugging a cross browser bug in my company's product I came across this.  I'm not certain what aspect of the JS sort method is involved.  The situation is we have and array of objects, each of which has a "name" property that's a string.  We want to sort the array, so I called

sorted_ar = ar.sort(function(a,b){
	return a.name > b.name;
});

This worked fine in Firefox on Windows and Snow Leopard, in Chrome on Windows and Snow Leopard, but failed in IE7 (meh) and Safari on both platforms.  I tried the WebKit nightly build (Version 4.0.4 (6531.21.10, r57054)) and it failed there too.  

Here's a complete test case:

-----
var ar = new Array();
if (console == undefined) {
    var console = {
    log : function(s) { print(s) }
    }
 }
ar[0] = {name: "zzz"};
ar[1] = {name: "qqq"};
ar[2] = {name: "mmm"};
ar[3] = {name: "aaa"};

function dump(a) {
    for(i=0; i< a.length; i++) {
        console.log(i + ": "+a[i].name);
    }
}


dump(ar);
console.log("sorting");
sorted_ar = ar.sort(function(a,b){
    console.log("services.sort: comparing "+a.name+" to "+b.name);
	return a.name > b.name;
});

dump(ar);
-----
(I added the console definition so it would run in a command line JS shell).

The successful results look like this (FF/Mac):


----
0: zzz
1: qqq
2: mmm
3: aaa
sorting
services.sort: comparing zzz to qqq
services.sort: comparing zzz to mmm
services.sort: comparing qqq to mmm
services.sort: comparing zzz to aaa
services.sort: comparing qqq to aaa
services.sort: comparing mmm to aaa
0: aaa
1: mmm
2: qqq
3: zzz
----

and the failing ones like thi (Safari/Mac)s:

----
0: zzz
1: qqq
2: mmm
3: aaa
sorting
services.sort: comparing qqq to zzz
services.sort: comparing mmm to zzz
services.sort: comparing mmm to qqq
services.sort: comparing aaa to qqq
services.sort: comparing aaa to mmm
0: zzz
1: qqq
2: mmm
3: aaa
----

This should be easy to reproduce by opening a WebInspector window and pasting the test code into the console.
Comment 1 Oliver Hunt 2010-04-05 16:25:19 PDT
Created attachment 52586 [details]
Test case as an html file

The problem with your test case is that your code is wrong.

the comparator function you provide returns inconsistent values which per spec results in undefined sorting.

Your comparator function is returning either true or false when it should be returning -1, 0, or 1, this means your comparator is inconsistent  as if i pass the strings "a" and "b" in one order your comparison function returns true (eg. 1) -- meaning "greater" -- or the other order it returns false (eg. 0) -- meaning "same".

You can read the documentation at https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/sort