user1938653 user1938653 - 23 days ago 7
Javascript Question

Sort objects in an array by two different criteria

I have an array that looks something like this:

var arr = [{user: '3', cash: 2},
{user: 'tim', cash: 3},
{user: '5', cash: 2},
{user: 'noah', cash: 3}]


I sort it by top earners like this:

arr.sort(function (a, b) {
return b.tS - a.tS;
});


It works fine, but after I've sorted the guys with the highest cash I want to also sort everyone alphabetically by the user field. Keep in mind that some of the users may have numbers but of type String (not Number).

I can't use libraries and I'd prefer it to work as fast as possible machine-wise.

Answer

You could chain the sorting criteria.

The chaining works for every step where the former delta is zero. Then the next delta, or comparison function is evaluated and early returned, if the value is different from zero.

Here, with only two sort groups is the value returned, but for longer chains, the next comparison is made.

var arr = [{ user: '3', cash: 2 }, { user: 'tim', cash: 3 }, { user: '5', cash: 2 }, { user: 'noah', cash: 3 }];

arr.sort(function (a, b) {
    return b.cash - a.cash || a.user.localeCompare(b.user);
});

console.log(arr);
.as-console-wrapper { max-height: 100% !important; top: 0; }

To get a sort with index, you need to store the index in a temporary array and use sorting with map.

var array = [{ user: '3', cash: 2 }, { user: 'tim', cash: 3 }, { user: '5', cash: 2 }, { user: 'noah', cash: 3 }];

// temporary array holds objects with position and sort-value
var mapped = array.map(function(el, i) {
    return { index: i, cash: el.cash };
});

// sorting the mapped array containing the reduced values
mapped.sort(function(a, b) {
    return  b.cash - a.cash || a.index - b.index;
});

// container for the resulting order
var result = mapped.map(function(el){
    return array[el.index];
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments