【问题标题】:Using Javascript with Underscore.js to Sort the other way使用 Javascript 和 Underscore.js 以另一种方式排序
【发布时间】:2012-01-02 18:10:11
【问题描述】:

我正在使用 Javascript sort(带有 Underscore.js):

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

我希望数组以另一种方式返回。我该怎么做?

[“玛丽”、“鲍勃”、“爱丽丝”]

我不想在排序后反转它 - 我希望它在第一次时以相反的方式创建。

谢谢。

【问题讨论】:

  • 你意识到最终可能只是对数组进行正常排序会更快,然后调用reverse()?
  • 排序然后反转也比其他选项更具可读性。

标签: javascript sorting underscore.js


【解决方案1】:

我宁愿将它与Array.reverse 一起使用,以充分利用两者的优点。

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

【讨论】:

  • 另外,你可以使用下划线的 _.identity 函数代替 function(name) {return name}:_.sortBy(["Bob", "Mary", "Marley", "Alice" ], _.identity).reverse()
  • 我不会这样称呼它更优雅,因为.reverse() 调用在数组中添加了另一个循环。因此,它实际上比 Felix 建议的反向排序效率低。
  • “快速编写好代码比快速编写好代码更容易。” (这归功于某个大师,我不记得之前是谁说过的)这更“优雅”,如果需要速度,默认排序可能就足够了;但如果速度是主要关注点,那么 JS 并不是目前最快的技术。
  • 这是一种执行循环两次。第一次迭代。 _.sortBy(["Bob", "Mary", "Alice"], function (name) {return name}) 第二次迭代 .reverse() 更好地处理 _sortBy
【解决方案2】:

我会做 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(...)

【讨论】:

  • 当我将小于号反转为大于时,它对我有用
【解决方案3】:

显然你不应该这样做,因为排序更有意义,然后反转结果,但如果你真的想在 sort 函数中以相反的顺序排序,你可以做这样的事情......

_.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');
};

【讨论】:

    【解决方案4】:

    您可以在 ES6 中使用 1 行来做到这一点,只需根据您想要的方向更改 &gt;。

    .sort() 从 IE6 开始支持,您只需传递一个返回 1 或 -1 的函数;

    ["Bob", "Mary", "Alice].sort((a, b) => a > b ? 1 : -1);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-11
      • 1970-01-01
      • 1970-01-01
      • 2017-11-23
      • 2013-09-29
      • 1970-01-01
      • 2023-02-26
      • 1970-01-01
      相关资源
      最近更新 更多