Question

There's a nifty method to sort an array of objects based on several properties:

var data = _.sortBy(array_of_objects, ['type', 'name']);

However that is only for ascending sorting. Is there some handy way of defining direction per column? E.g.

var data = _.sortBy(array_of_objects, [{'type': 'asc'}, {'name': 'desc'}]);
Was it helpful?

Solution

As of lodash 3.5.0 you can use sortByOrder (renamed orderBy in v4.3.0):

var data = _.sortByOrder(array_of_objects, ['type','name'], [true, false]);

Since version 3.10.0 you can even use standard semantics for ordering (asc, desc):

var data = _.sortByOrder(array_of_objects, ['type','name'], ['asc', 'desc']);

In version 4 of lodash this method has been renamed orderBy:

var data = _.orderBy(array_of_objects, ['type','name'], ['asc', 'desc']);

OTHER TIPS

You can always use Array.prototype.reverse()

var data = _.sortBy(array_of_objects, ['type', 'name']).reverse();

Deep field & multi field & different direction ordering Lodash >4

var sortedArray = _.orderBy(mixedArray,
                            ['foo','foo.bar','bar.foo.bar'],               
                            ['desc','asc','desc']);

It's worth noting that if you want to sort particular properties descending, you don't want to simply append .reverse() at the end, as this will make all of the sorts descending.

To make particular sorts descending, chain your sorts from least significant to most significant, calling .reverse() after each sort that you want to be descending.

var data = _(data).chain()
    .sort("date")
    .reverse()    // sort by date descending
    .sort("name") // sort by name ascending
    .result()

Since _'s sort is a stable sort, you can safely chain and reverse sorts because if two items have the same value for a property, their order is preserved.

More information

In the documentation of the version 4.11.x, says: ` "This method is like _.sortBy except that it allows specifying the sort orders of the iteratees to sort by. If orders is unspecified, all values are sorted in ascending order. Otherwise, specify an order of "desc" for descending or "asc" for ascending sort order of corresponding values." (source https://lodash.com/docs/4.17.10#orderBy)

let sorted = _.orderBy(this.items, ['fieldFoo', 'fieldBar'], ['asc', 'desc'])

Is there some handy way of defining direction per column?

No. You cannot specify the sort order other than by a callback function that inverses the value. Not even this is possible for a multicolumn sort.

You might be able to do

 _.each(array_of_objects, function(o) {
     o.typeDesc = -o.type; // assuming a number
 });
 _.sortBy(array_of_objects, ['typeDesc', 'name'])

For everything else, you will need to resort to the native .sort() with a custom comparison function:

 array_of_objects.sort(function(a, b) {
     return a.type - b.type // asc
         || +(b.name>a.name)||-(a.name>b.name) // desc
         || …;
 });

You can also try this:

var data= _.reverse(_.sortBy(res.locals.subscriptionList.items, ['type', 'name']));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top