Daniel Kaplan Daniel Kaplan - 6 months ago 29
Javascript Question

How can I use lodash/underscore to sort by multiple nested fields?

I want to do something like this:

var data = [
{
sortData: {a: 'a', b: 2}
},
{
sortData: {a: 'a', b: 1}
},
{
sortData: {a: 'b', b: 5}
},
{
sortData: {a: 'a', b: 3}
}
];

data = _.sortBy(data, ["sortData.a", "sortData.b"]);

_.map(data, function(element) {console.log(element.sortData.a + " " + element.sortData.b);});


And have it output this:

"a 1"
"a 2"
"a 3"
"b 5"


Unfortunately, this doesn't work and the array remains sorted in its original form. This would work if the fields weren't nested inside the
sortData
.
How can I use lodash/underscore to sort an array of objects by more than one nested field?

I've turned this into a lodash feature request: https://github.com/lodash/lodash/issues/581

Answer

There is a _.sortByAll method in lodash version 3:

https://lodash.com/docs#sortByAll

Other option would be to sort values yourself:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

function compareValues(v1, v2) {
    return (v1 > v2) 
        ? 1 
        : (v1 < v2 ? -1 : 0);
};


var data = [
    { a: 2, b: 1 },
    { a: 2, b: 2 },
    { a: 1, b: 3 }
];

data.sort(function (x, y) {
    var result = compareValues(x.a, y.a);

    return result === 0 
        ? compareValues(x.b, y.b) 
        : result;
});

// data after sort:
// [
//     { a: 1, b: 3 },
//     { a: 2, b: 1 },
//     { a: 2, b: 2 }
// ];