我有一个像这样的数组:
[nil, nil, nil, 2, 4, 6, 1, nil, nil, 3, 4, 6]
我需要的是一个很好的方法来删除所有前导 nils(因此compact!
很糟糕),并删除了nils的数量(所以drop_while
很糟糕)。
答案 0 :(得分:6)
以下是三种方法。请注意,以下内容经过了多次修改。
arr0 = [nil, nil, nil, 2, 4, 6, 1, nil, nil, 3, 4, 6]
arr1 = [nil, nil]
arr2 = [1, 2]
<强>#1 强>
def remove_leading_nils(arr)
i = arr.index { |e| !e.nil? } || arr.size
arr.slice!(0...i)
i
end
remove_leading_nils(arr0) #=> 3
arr0 #=> [2, 4, 6, 1, nil, nil, 3, 4, 6]
remove_leading_nils(arr1) #=> 2
arr1 #=> []
remove_leading_nils(arr2) #=> 0
arr2 #=> [1,2]
<强>#2 强>
def remove_leading_nils(arr)
arr.size.times.with_object([]) { |_,a| a << arr.shift unless arr.first }.size
end
<强>#3 强>
我更喜欢这个,因为它更简单,我觉得它最好:
def remove_leading_nils(arr)
sz = arr.size
arr.shift while !arr.empty? && arr.first.nil?
sz - arr.size
end
与方法#1一样,方法#2和#3与arr0
,arr1
和arr2
具有相同的返回值。
答案 1 :(得分:2)
可能不是一个好主意,但如果你坚持单行:
arr.instance_eval { shift(index { |element| !element.nil? } || size) }.count
<小时/> 编辑:对于任何人未来的参考,我们同意的更好看的版本:
arr.shift(arr.index(&:itself) || arr.size).count