如果我在 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
如何解决?
谢谢之前
处理零,这会让你接近......
2.1.2 :010 > my_array.sort { |x,y| x && y ? (x <=> y) : (x ? -1 : 1) }
=> ["12", "12 months", "13 months", nil, nil]
这并不准确,根据
'12'
的比较,<=>
排在其他之前。如果您想要更多控制,您需要有一个更复杂的比较块。
这是一个很好的简短方法,但只有当你能想出一个保证“大于”数组中所有字符串的字符串时,它才会起作用(这在这里很容易):
my_array.sort_by { |x| x || "Z" }
=> ["12", "12 months", "13 months", nil, nil]
您可以比较二维数组:字符串是否为零以及字符串本身。
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]
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]
我喜欢这个的是:
数组是否包含字符串、整数或其他任何内容都没关系,因此您不需要使用任意值分配给
nil
来对它们进行最后或第一个排序。
它使用标准的
.sort
方法,因此不会覆盖任何内容并利用已有的功能。
您可以首先(默认)或最后(通过传递
nil
参数)对 nils_first: false
值进行排序。
它会保留
nil
值的数量(如果这很重要),然后您可以使用 .uniq
将其减少为单个 nil
值(如果您愿意)。
操作不是就地,因此不会影响原始Array对象。