Sort array of objects by value using underscore.js [closed]

江枫思渺然 提交于 2019-12-10 18:44:47

问题


I'm trying to sort an array of objects by the average property in descending order - so the largest average is first - but am not able to using 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


回答1:


The issue here is that you wanted the array to be sorted in descending order by average, instead of the default ascending order.

You could do this by providing a custom iteratee to the _.sortBy() function:

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

Updated fiddle

But I don't recommend that. It would be much better to simply use the native JavaScript [].sort() method and provide it a comparison function:

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

Better fiddle

If you were sorting a very large array, this would also be faster than using _.sortBy(). Look at the source code for _.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's doing quite a bit of work in addition to the .sort() call - and this code is just the tip of the iceberg, the helper functions it calls like cb() do a lot of work too.

Why do all that when it's just as easy to call .sort() directly yourself?

Also, it takes a close reading of that lengthy .sortBy() source to be sure that it does a numeric sort instead of a lexicographic sort - and the documentation doesn't say!

A lexicographic sort (aka alphabetic sort) is where the values are sorted as strings, not as numbers. So for example it would use this order:

[ 1424, 2367, 241, ... ]

When you call the native array .sort() yourself, you can easily verify that it uses a numeric sort: the value b.average - a.average is always a number.



来源:https://stackoverflow.com/questions/30155414/sort-array-of-objects-by-value-using-underscore-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!