【问题标题】:How to use sort_by when you have a nil value and multiple sorts当你有一个 nil 值和多个排序时如何使用 sort_by
【发布时间】:2018-07-09 23:39:24
【问题描述】:

我有一组调用,我想先按 schedule_date 排序,然后再按 trigger_date 排序。

calls.sort_by! { |call| [call.scheduled_date, call.triggered_date] }

因为triggered_date 有时是一个零值,我得到了错误 #<ArgumentError: comparison of Array with Array failed>

如何对它进行排序以考虑 nil 值?我用谷歌搜索了一些例子,但找不到与我所拥有的类似的东西。比如我试过

calls.sort_by! { |call| [call.scheduled_date, call.triggered_date] } rescue nil

calls.sort_by! { |call| [call.scheduled_date, call.triggered_date] || call.scheduled_date }

但它们不起作用。我已经看到 <=> 用于 sort_by 但不确定如何在有多种排序的情况下使用它。任何帮助将不胜感激。

【问题讨论】:

  • 您希望如何处理 nil 值?您是否希望在非nil 对应对象之前或之后进行排序,例如nil 应该是“1900-01-01”还是“9999-12-31”
  • 好问题。现在我想一想 - 如果triggered_date 为零,那么我想使用scheduled_date.end_of_day 作为替代品。
  • 哦。然后忽略我刚刚发布的答案并尝试calls.sort_by! { |call| [call.scheduled_date, call.triggered_date || call.scheduled_date.end_of_day ] }或类似的东西?
  • 效果很好。谢谢!我想我无法弄清楚语法。 :)
  • 我更新了我的答案,以防你想接受这个作为解决方案。干得好@engineersmnky 提出了正确的问题!

标签: ruby


【解决方案1】:

如果您对可能丢失的triggered date 有一个首选替换值,如您在评论中提到的,可能是call.scheduled_date.end_of_day,您可以执行以下操作:

calls.sort_by! { |call| [call.scheduled_date, call.triggered_date || call.scheduled_date.end_of_day] }

那么数组的第二个条目将是triggered_date(如果存在)和call.scheduled_date.end_of_day(如果triggered_datenil)。

旧答案:

如果您希望 nil-part 在您的排序中被忽略(即带有 triggered_date == nil 的条目被认为比带有 triggered_date 的条目“更小”,您可以执行以下操作:

calls.sort_by! { |call| [call.scheduled_date, call.triggered_date].compact }

compact 从数组中删除 nil 值。因此,没有triggered_date 的调用只有一个大小为 1 的数组用于比较,而其他的数组大小为 2。短小似乎在这里获胜,所以这些被排序在任何其他的前面。

如果scheduled_date 也可能是nil,请注意!那么这种方法会导致非常奇怪的结果。

已编辑:如果可能的后备已知,则添加解决方案

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    相关资源
    最近更新 更多