Vinnie James
Vinnie James

Reputation: 6042

How can I ensure a stable array.sort() order, javascript

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

Answers (3)

Brian Glaz
Brian Glaz

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

Nina Scholz
Nina Scholz

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

glass duo
glass duo

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

Related Questions