I have a sorting anomaly that I can reproduce in Chrome Version 28.0.1500.71 Ubuntu 12.04 (28.0.1500.71-0ubuntu1.12.04.1), which is all I have available to me today, but I have seen the same results in Firefox's latest version as well.
Given the following code:
<SCRIPT type="text/javascript">
var ary=[];
for(var x=0; x<11; x++){
var tmp=[];
tmp[0]="COL" + ("00" + x).substr(-3);
tmp[1]= Math.floor(x/3);
ary[x]=tmp;
}
ary.sort(function(a,b){
if(a[0]>b[0]){return 1}
if(a[0]<b[0]){return -1}
return 0;
});
console.log(ary.toString());
ary.sort(function(a,b){
if(a[1]>b[1]){return 1}
if(a[1]<b[1]){return -1}
return 0;
});
console.log(ary.toString());
</SCRIPT>
As you can (potentially) see, the results of the first sort display that ary[] is sorted correctly by column 0, but after the second sort, when a[1]==b[1], the sort that was previously performed is now (potentially) reversed.
If there are fewer iterations of x, the second sort (potentially) returns expected results.
I have seen this for a while, but now I need to be able to sort as many as 15000 rows by one arbitrary column and then another, and then yet another, without losing the sort orders of the previous sorts when a[?]==b[?]. I would assume this to be expected behavior.
I'm guessing that it's a time-saving feature built into javascript's sorting algorithm, but with an unforeseen side-affect.
Is there a magic bullet that will keep me from having to loop through each previous sort when a==b in the current sort?
EDIT: @ameer: Okay, is this a feasible "magic bullet"?
We can add an index value to the array, and when we sort, if our values are equal, we can then sort by the index itself.
for(var x=0; x<ary.length; x++){ary[x].index = x;}
ary.sort(function(a,b){
if(a[2]>b[2]){return 1;}
if(a[2]<b[2]){return -1;}
if(a.index>b.index){
return 1;
}
return -1;
});
When we put the index in, we can know what the previous sort did to the array, and maintain that sort order should a[?]==b[?] in our current sort.
I wonder just how fast this is - I would also like to know how to renumber the indexes during the sort, rather than recreating them before each sort, but I'm afraid it would throw off the sort for equal values. Perhaps we can add a newIndex property that changes during the sort, and set index's value to the newIndex value afterwards.
Any suggestions?