如果值不为零,则按值对哈希数组进行排序(使用 sort_by)

Sort an array of hashes by value if such value is not nil (using sort_by)

我正在尝试对哈希执行 sort_by,但每当我有一个 nil 值时,我得到: comparison of DateTime with nil failed

我的目标是在 sort_by 方法中对 x[:last_posted_at] 执行零检查 (.present?)。那可能吗?示例代码:

posts = [
  { "name"=>"Alice", "last_posted_at"=> some_datetime },
  { "name"=>"Bob",   "last_posted_at"=> nil},
  { "name"=>"Clark", "last_posted_at"=> some_datetime - 1}
]

# expected result
posts.sort_by.{ |x| x[:last_posted_at] } #compare only if value is not nil
  #=> [{"name"=>"Alice", "last_posted_at"=> some_datetime},
  #    {"name"=>"Clark", "last_posted_at"=> some_datetime - 1},
  #    {"name"=>"Bob",   "last_posted_at"=> nil}]

我查看了 sort_by 文档和 Whosebug 中的一些帖子,但找不到我的答案。欢迎任何帮助或链接!提前致谢!

使用 presence 到 return 值或 nil|| 到 return 默认值(如果为空)。

# Something sufficiently old to be older than any other time.
nil_time = Time.at(0)
posts.sort_by.{ |x|
  x[:last_posted_at].presence || nil_time
}

注:DateTime is deprecated.

我喜欢 Schwern 的方法。但是,如果有更多没有日期的记录,那么另一种选择可能是将没有日期的记录与有日期的记录分开,并且只对有日期的记录进行排序,如下所示:

posts
  .partition { |v| v['last_posted_at'] }                   # separate by date presence
  .tap { |v| v.first.sort_by! { |v| v['last_posted_at']} } # only sort entries with a date
  .flatten                                                 # combine into one list again