Reputation: 6042
How can I ensure a stable .sort() order across all browsers? JavaScript
I have an array of objects, eg
[{
thing: 'walker',
value: 1
},
{
thing: 'texas',
value: 2
},
{
thing: 'ranger',
value: 2
}]
When sorting the array I sort them alternating asc/desc using:
_sortNumber (key, dir) {
return function(a, b) {
if (dir) {
// sort descending
return b[key] - a[key];
}
else {
// sort ascending
return a[key] - b[key];
}
}
};
array.sort(this._sortNumber('value', Boolean));
However, the order of texas
and ranger
seem to randomly change. I believe due to the fact that they are the same number, however, I would like it to be consistent.
How can I ensure consistency; or sort on a secondary value (eg thing
alphabetically), in order to ensure I always get the same sort result?
Upvotes: 1
Views: 2374
Reputation: 15666
Since you are writing your own sorting function anyway, you can just define what the logic should be when the values are equal.
_sortNumber (key, dir) {
return function(a, b) {
if (dir) {
// sort descending
if( a[key] !== b[key])
{
return b[key] - a[key];
} else { //They are same.. sort by something else
if (a.thing < b.thing){
return 1;
}else if (a.thing > b.thing){
return -1;
}else{
return 0;
}
}
else {
// sort ascending
if( a[key] !== b[key])
{
return a[key] - b[key];
} else {
if (a.thing < b.thing){
return -1;
}else if (a.thing > b.thing){
return 1;
}else{
return 0;
}
}
}
}
};
Upvotes: 3
Reputation: 386530
First of all, like Array#sort
and other sort implementations:
The sort is not necessarily stable.
To maintain a stable sort, you could use a unique value, like an index as last sort value in the chain of sorting criteria, like
function asc(key) {
return function (a, b) {
return a[key] - b[key] || a.id - b.id;
};
}
array.sort(asc('value'));
Upvotes: 3
Reputation: 414
You need to sort not only by value
but also by thing
see this post: How to sort an array of objects by multiple fields?
If you use Excel and you've ever set the criteria for sort, you've seen how they give you the first, second, third, etc, fields to sort by. That's what you need to do. Set the first field as value
and the second field as thing
The post I shared gives the code to do that.
Upvotes: 1