如果数组内有 nil 对象,如何在 ruby 中对数组进行排序?

问题描述 投票:0回答:4

如果我在 ruby 中有这样的数组,如何对数组进行排序?

示例:

my_array = ["12 months", "13 months", nil, nil, "12"]

我想要得到这样的结果:

 my_array = ["12", "12 months", "13 months", nil, nil]

当我尝试时:

my_array.sort{|x, y| x <=> y}

我收到这样的错误:

ArgumentError Exception: comparison of String with nil failed

如何解决?

谢谢之前

ruby arrays
4个回答
3
投票

处理零,这会让你接近......

2.1.2 :010 > my_array.sort { |x,y| x && y ? (x <=> y) : (x ? -1 : 1) }
 => ["12", "12 months", "13 months", nil, nil] 

这并不准确,根据

'12'
的比较,
<=>
排在其他之前。如果您想要更多控制,您需要有一个更复杂的比较块。


2
投票

这是一个很好的简短方法,但只有当你能想出一个保证“大于”数组中所有字符串的字符串时,它才会起作用(这在这里很容易):

my_array.sort_by { |x| x || "Z" }
=> ["12", "12 months", "13 months", nil, nil]

0
投票

您可以比较二维数组:字符串是否为零以及字符串本身。

my_array = ["12 months", "13 months", nil, nil, "12"]

my_array.sort_by { |x| [x ? 0 : 1, x] }
=> ["12", "12 months", "13 months", nil, nil]

0
投票

创建一个
Array#sort_with_nils
方法。

如果您需要一次或两次以上,添加初始化器并向

#sort_with_nils
添加
Array
方法可能会很有用。像这样的东西:

config/initializers/array.rb

def sort_with_nils( nils_first: true )
  nils = [ nil ] * self.tally[ nil ] # Counts the number of `nil` values and create an Array of that number of `nil` values. We will add this to the beginning or the end of the Array after sorting.

  if nils_first
    nils + ( self - [ nil ] ).sort
  else
    ( self - [ nil ] ).sort + nils
  end
end

示例:

myarray = [ 1, 2, nil, 4, nil ]
#=> [1, 2, nil, 4, nil]
myarray.sort_with_nils
#=> [nil, nil, 1, 2, 4]
myarray
#=> [1, 2, nil, 4, nil]
myarray.sort_with_nils( nils_first: false )
#=> [1, 2, 4, nil, nil]
myarray
#=> [1, 2, nil, 4, nil]

我喜欢这个的是:

  1. 数组是否包含字符串、整数或其他任何内容都没关系,因此您不需要使用任意值分配给

    nil
    来对它们进行最后或第一个排序。

  2. 它使用标准的

    .sort
    方法,因此不会覆盖任何内容并利用已有的功能。

  3. 您可以首先(默认)或最后(通过传递

    nil
    参数)对
    nils_first: false
    值进行排序。

  4. 它会保留

    nil
    值的数量(如果这很重要),然后您可以使用
    .uniq
    将其减少为单个
    nil
    值(如果您愿意)。

  5. 操作不是就地,因此不会影响原始Array对象。

© www.soinside.com 2019 - 2024. All rights reserved.