Sorting array of objects by value with underscore.js

I'm trying to sort an array of objects using a property average

in descending order - so the very first average

is the first, but I can't use underscore.js. Below is my attempt:

var jsonData = [
{
    "title": "Dear Kitten",
    "totalCount": 1689,
    "average": 241
},
{
    "title": "Weird Things All Couples Fight About",
    "totalCount": 9966,
    "average": 1424
},
{
    "title": "If Disney Princesses Were Real",
    "totalCount": 16567,
    "average": 2367
},
{
    "title": "Secret Tricks With Everyday Objects",
    "totalCount": 24884,
    "average": 3555
},
{
    "title": "The Coolest Travel Hacks",
    "totalCount": 41847,
    "average": 8369
},
{
    "title": "5 Ways You're Drinking Coffee Wrong",
    "totalCount": 55673,
    "average": 7953
},
{
    "title": "The Perfect Way To Pour A Beer",
    "totalCount": 58097,
    "average": 58097
},
{
    "title": "Fruit You're Eating Wrong",
    "totalCount": 65570,
    "average": 32785
},
{
    "title": "Your Cat Is Judging You",
    "totalCount": 78952,
    "average": 11279
},
{
    "title": "3rd Date vs 30th Date",
    "totalCount": 84394,
    "average": 14066
}
];

console.log(_.sortBy(jsonData, "average"));

      

jsFiddle

+3


source to share


1 answer


The problem is that you wanted the array to be sorted in descending order by average

, not ascending.

You can do this by providing a custom iteratee

function _.sortBy()

:

_.sortBy( jsonData, function( item ) { return -item.average; } )

      

Updated violin

But I don't recommend this. It would be much easier to just use a native JavaScript method [].sort()

and provide a comparison function to it:

jsonData.sort( function( a, b ) { return b.average - a.average; } )

      

Best Violin

If you were sorting a very large array, this would also be faster than using _.sortBy()

. Take a look at the source code _.sortBy()

to see why:



_.sortBy = function(obj, iteratee, context) {
  iteratee = cb(iteratee, context);
  return _.pluck(_.map(obj, function(value, index, list) {
    return {
      value: value,
      index: index,
      criteria: iteratee(value, index, list)
    };
  }).sort(function(left, right) {
    var a = left.criteria;
    var b = right.criteria;
    if (a !== b) {
      if (a > b || a === void 0) return 1;
      if (a < b || b === void 0) return -1;
    }
    return left.index - right.index;
  }), 'value');
};

      

It does quite a lot of work in addition to the call .sort()

- and this code is just the tip of the iceberg, the helper functions it calls, for example, cb()

do a lot of work.

Why is all this when it's just so easy to call it .sort()

yourself?

Also, he reads this long .sortBy()

source carefully to make sure he is doing a numeric sort instead of a lexicographic sort - and the documentation is not telling !

Lexicographic sort (aka alphabetical sort) is where values ​​are sorted as strings, not numbers. So, for example, it will use this order:

[ 1424, 2367, 241, ... ]

      

When you call your own array .sort()

yourself, you can easily make sure that it uses a numeric sort: the value is b.average - a.average

always a number.

+2


source







All Articles