【问题标题】:How do I sort objects by a certain field (like _.sortBy) in plain JS?如何在纯 JS 中按某个字段(如 _.sortBy)对对象进行排序?
【发布时间】:2015-09-07 08:50:14
【问题描述】:

我正在尝试根据数组对象的一个​​属性start 对数组进行排序。

events = _.sortBy(events, function(a) {
    return moment(new Date(a.start)).format();
});

这给了我正确的结果。但是,以下没有。

events = events.sort(function(a, b) {
    return moment(new Date(a.start)).format() > moment(new Date(b.start)).format();
});

有人知道发生了什么吗?

小提琴:https://jsfiddle.net/q24zx11h/1/

【问题讨论】:

  • sort 函数参数应返回 {-1; 0; 1} 之一,而不是布尔值。顺便说一句,您是否有理由将日期对象包装在 moment 对象中?
  • 不用foo = foo.sort(..).sort有副作用/修改原数组
  • 我只是想比较一下时间而已。我做moment(new Date(xxx)) 而不仅仅是moment(xxx) 因为后者有时会给我警告信息。也许我做的事情没有必要?
  • 好的,我意识到也许我不应该比较字符串。更容易进行(new Date(b)).getTime() 比较。谢谢

标签: javascript sorting momentjs lodash


【解决方案1】:

比较函数必须返回 -1、0 或 1:

function compare(a, b) {
  if (a is less than b by some ordering criterion) {
    return -1;
  }
  if (a is greater than b by the ordering criterion) {
    return 1;
  }
  // a must be equal to b
  return 0;
}

目前您的代码返回布尔值,我认为它被解析为 0 或 1,因此您的代码运行但不正确。

【讨论】:

    【解决方案2】:

    比较器函数通常返回一个整数参数,指示以下值:

    • -1: a 小于 b
    • 0:a 等于 b
    • 1:a大于b

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

    一个方便的技巧是从b 的离散值中减去a 的离散值,在您的情况下,例如使用时间戳:

    function (a, b) { return (new Date(b)).getTime() - (new Date(a)).getTime(); }
    

    如果 b 现在大于 a,它将返回一个正值,依此类推。

    【讨论】:

    • @Shih-MinLee 如果回答了您的问题,请接受答案:)
    • 我会使用 lodash,但在不使用外部库时这应该是正确的。谢谢!
    【解决方案3】:

    the docs of Array.sort 是这么说的:

    arr.sort([compareFunction])

    如果提供了 compareFunction,则对数组元素进行排序 根据比较函数的返回值。如果 a 和 b 是 比较两个元素,然后:

    • 如果 compareFunction(a, b) 小于 0,则将 a 排序到比 b 低的索引,即 a 排在第一位。
    • 如果 compareFunction(a, b) 返回 0,则保持 a 和 b 相对于彼此保持不变,但相对于所有不同的排序 元素。注意:ECMAscript 标准不保证这一点 行为,因此并非所有浏览器(例如 Mozilla 版本约会 至少回到 2003 年)尊重这一点。
    • 如果 compareFunction(a, b) 大于 0,则将 b 排序到比 a 低的索引。
    • compareFunction(a, b) 在给定一对特定元素 a 和 b 作为其两个参数时,必须始终返回相同的值。如果 返回不一致的结果,则排序顺序未定义

    您的函数返回一个布尔值,然后将其转换为Number,即01,在这种情况下0 表示相等(因为“这些元素相同,请将它们放入任何顺序”)。

    【讨论】:

      【解决方案4】:

      我发现两个代码的结果相同

          var manualSort = days.sort(function(a, b) {
              return moment(new Date(a.start)).format() > moment(new Date(b.start)).format();
          });
      
          var underScoreSort = _.sortBy(days, function(a) {
              return moment(new Date(a.start)).format();
          });
      

      两个数组返回相同的结果。

      【讨论】:

      • 我认为不应该。第一个结果搞砸了。
      • 我试过在 days 数组中只有 2 个对象。它显示了相同的结果。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-05
      • 2011-10-18
      • 2017-05-01
      相关资源
      最近更新 更多