Stiger Stiger - 6 months ago 18
Javascript Question

Multi-sorting in underscore

I have Array object

ArrObject


object = {
Active: true, // type: boolean
Code: '12345' // type: string
}


I want to sort this array by
Active
field then
Code
. I need help to do that with
underscoreJs
.

UPDATE

My data:

data = [
{
Code: "Code0",
Description: "Description0",
IsActive: true,
id: 0
},
{
Code: "Code1",
Description: "Description1_edit",
IsActive: true,
id: 1
},
{
Code: "Code5",
Description: "Description5_edit",
IsActive: false,
id: 2
}]

Answer

I'd just use Array#sort with a simple comparator function:

function cmp_bool(a, b) {
    return a == b ?  0
         : a      ? -1
         :          +1
}
function cmp_str(a, b) {
    return a == b ?  0
         : a <  b ? -1
         :          +1
}
function cmp(a, b) {
    return cmp_bool(a.IsActive, b.IsActive)
        || cmp_str( a.Code,     b.Code);
}

Then you could simply do this:

var sorted = data.sort(cmp);

If you need to be able to switch the Code sort order then you just need a reversed version of cmp_str (say cmp_str_reverse) and a version of cmp that uses cmp_str_reverse instead of cmp_str.

If you must use _.sortBy then you just need to come up with a value to sort by, something like this:

function combined(obj) {
    return (obj.IsActive ? 'a' : 'b')
         +  obj.Code;
}
var sorted = _(data).sortBy(combined);

The problem with this is that it is much harder to reverse the Code ordering. I suppose you could do a big mess of bit twiddling on the string's characters but that would just leave you wonder just what you were doing when you look at the code in six months. _.sortBy is a notational convenience, you don't have to force everything to fit whatever conveniences you have on hand.

Demo: http://jsfiddle.net/ambiguous/6tfcQ/

Comments