使用Javascript和Underscore.js实现反向排序

41

我正在使用带有Underscore.js的Javascript sort函数:

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

我希望数组以相反的顺序返回。我应该怎么做?

["Mary", "Bob", "Alice"]

我不想在排序后再进行反转 - 我想第一次就是相反的顺序创建。

谢谢。


1
你意识到最终通常可能更快地对数组进行正常排序,然后调用 reverse() 函数吗? - David Thomas
排序然后反转也比其他选项更易读。 - Felix Loether
4个回答

80

与其丢弃 underscorejs,我宁愿与 Array.reverse 一起使用,以发挥二者的优势。

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

9
除了使用函数(name) {return name}外,您还可以使用下划线的_.identity函数: _.sortBy(["Bob", "Mary", "Marley", "Alice"], _.identity).reverse() - djKianoosh
4
我不会称这更优雅,因为.reverse()调用会使数组再进行一次遍历。所以实际上比起像 Felix 建议的只是反向排序,这更低效。 - Mikel
1
“编写好的代码快速完成比编写快速的代码变得更好容易。”(归功于某位大师,我无法回忆起他之前说过什么)如果需要速度,则默认排序可能足够优雅;但是,如果速度是主要问题,则JS不是最快的技术。 - Txangel
这有点像是执行了两次循环。第一次迭代:_.sortBy(["Bob", "Mary", "Alice"], function (name) {return name}) 第二次迭代:.reverse() 最好在 _sortBy 中处理。 - Praveen

35

我会像Underscore在幕后所做的那样:使用Array#sort方法。

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

如果您不想修改原始数组,请先克隆它:

_.clone(["Bob", "Mary", "Alice"]).sort(...)

当我将小于号反转为大于号时,它对我起作用了。 - Mohammad Mudassir

0
显然,你不应该这样做,因为更明智的做法是先排序,然后反转结果,但如果你真的想在排序函数内部按相反顺序排序,你可以像这样做...
_.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('');
});

...还值得注意的是,下划线与本地JavaScript排序略有不同,因为存在一个小型跨平台问题,涉及一致的排序顺序...

如果compareFunction (a,b)返回0,则将a和b保持不变相对于彼此,但相对于所有不同的元素进行排序。注意:ECMAscript标准不保证此行为,因此并非所有浏览器(例如至少可以追溯到2003年的Mozilla版本)都支持这一点。Array.prototype.sort()

Underscore的.sortBy文档规定:

返回列表的(稳定)排序副本。_.sortBy

它通过返回左侧索引减去右侧索引的索引而不是返回 0 来保持项目顺序。

_.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
你可以用 ES6 中的一行代码来实现这个,只需根据所需方向更改 > 即可。 .sort() 自 IE6 起已受支持,您只需传递一个返回 1 或 -1 的函数即可。
["Bob", "Mary", "Alice].sort((a, b) => a > b ? 1 : -1);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接