Using Javascript with Underscore.js to Sort the other way

前端 未结 4 840
长情又很酷
长情又很酷 2021-02-01 14:01

I\'m using Javascript sort (with Underscore.js):

_.sortBy([\"Bob\", \"Mary\", \"Alice\"], function (name) {return name})
> [\"Alice\", \"Bob\", \         


        
相关标签:
4条回答
  • 2021-02-01 14:11

    I would just do what Underscore does under the hood: use the Array#sort method.

    ["Bob", "Mary", "Alice"].sort(function (a, b) {
        if (a < b) return 1;
        if (b < a) return -1;
        return 0;
    });
    

    Or if you don't want the original array modified, clone it first:

    _.clone(["Bob", "Mary", "Alice"]).sort(...)
    
    0 讨论(0)
  • 2021-02-01 14:12

    Obviously you should not do this, as it makes far more sense to sort, then reverse the results, but if you really want to sort in reverse order inside the sort function, you could do something like this...

    _.sortBy(["Bob", "Mary", "Alice"], function (a) {
        // split each string into single characters
        // ... then swap for inverse character from unicode range
        // ... and glue the characters back together into an inversely sortable string
        return _.map(a.split(''), function(i){
            return String.fromCharCode(65536 - i.charCodeAt(0));
        }).join('');
    });
    

    ... also worth noting that underscore is subtly different than native javascript sort which has a small cross platform issue regarding consistent sort order...

    If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this. Array.prototype.sort()

    Underscore's .sortBy documentation states:

    Returns a (stably) sorted copy of list. _.sortBy

    Which it does by instead of returning 0 to keep items in order, it returns the index of the left side minus the index of the right side.

    _.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');
    };
    
    0 讨论(0)
  • 2021-02-01 14:29

    You can do this with a 1 liner in ES6, just change the > depending on the direction you want.

    .sort() is supported since IE6 and you just pass a function which returns 1 or -1;

    ["Bob", "Mary", "Alice].sort((a, b) => a > b ? 1 : -1);
    
    0 讨论(0)
  • 2021-02-01 14:30

    Instead of throwing underscorejs away, I'd rather use it together with Array.reverse to utilize the best of both.

    _.sortBy(["Bob", "Mary", "Alice"], function (name) {return name})
     .reverse()
    
    0 讨论(0)
提交回复
热议问题