【问题标题】:Sorting using sort_by with nils appearing in the front使用 sort_by 进行排序,其中 nil 出现在前面
【发布时间】:2016-03-02 10:06:05
【问题描述】:

有什么办法可以使用sort_by,让nils出现在前面。

例如

[-1, 2, 3, nil, nil].sort_by &some_block

应该给

#=> [nil, nil, -1, 2, 3]

它类似于this question,但那里的解决方案不适用于负值。

【问题讨论】:

  • 旁注:对链接问题的接受答案完全适用于否定,更重要的是,约翰的答案是它的精确副本。
  • @mudasobwa 我的错!对不起。答案是负面的。我不知道我是怎么错过的。
  • @Stefan,我不相信这是引用问题的重复。然而,即使是这样,那里的(两个)答案也不涵盖解决这个问题的可能方法的范围。另外:我发现在将问题标记为重复时,后者通常是一个问题。有时引用的问题没有好的答案。
  • @mudasobwa,差不多。我明确表示不会将falsenil 视为相同,但没有多大意义,因为无论如何布尔值都无法在Ruby 中进行比较。

标签: arrays ruby sorting


【解决方案1】:

如果您的其他值是数字,您可以使用Float::INFINITY

[-1, 2, 3, nil, nil].sort_by { |n| n || -Float::INFINITY }
#=> [nil, nil, -1, 2, 3]

另一种写法是:

sort_by { |n| n ? n : -Float::INFINITY }

或者更明确地提到nil

sort_by { |n| n.nil? ? -Float::INFINITY : n }

【讨论】:

    【解决方案2】:
    > [-1, 2, 3, nil, nil].sort_by{|x| [(x.nil?)?0:1, x]}
     => [nil, nil, -1, 2, 3] 
    

    这避免了将 int 与 nil 进行比较,通过利用 <=> 对数组的短路行为的优势

    【讨论】:

    • 我了解x.nil? 0:1 如何使它出现在正数之前,但不明白如何将 x 放在[(x.nil?)?0:1, x] 的末尾使其出现在负数之前?
    • @Lokesh 数组按元素进行比较,即[0, x] 位于[1, y] 之前,而不管xy。见Array#<=>
    • 好的。谢谢。你能帮我决定哪种方式性能更好吗?这是另一个还是你的@Stefan?
    • 比较数值无疑比比较数组要快。
    【解决方案3】:

    我建议

    def sort_by_with_val_first(arr, val=nil)
      ([val]*arr.count(val)).concat (arr-[val]).sort_by { |e| yield e }
    end
    
    arr = [-1, 2, 3, nil, nil, -4]
    sort_by_with_val_first(arr) { |x| x.abs }
      #=> [nil, nil, -1, 2, 3, -4]
    

    我喜欢这样写:“创建一个由 arr 中的元素 val 组成的数组,然后将此数组与 arr 连接,并删除元素 val,并按需要排序”。在我看来,将sort_by 中的val 转换为使其工作的人工值在美学上令人不快。

    【讨论】:

      猜你喜欢
      • 2014-06-13
      • 2021-07-26
      • 2012-07-16
      • 2011-05-21
      • 1970-01-01
      • 2014-02-27
      • 1970-01-01
      • 1970-01-01
      • 2016-10-06
      相关资源
      最近更新 更多