我有一个像这样的数组:
[["a", nil, nil, nil], ["b", nil, "c", nil], [nil, nil, nil, nil]]
我想从ruby中的数组中删除所有尾随的nil值。
我尝试了arr.map {|x| x.pop until x.last}
,但这种方法的问题在于,当给定数组中的第3个数组中的所有数组值都为nil时,循环卡住了。
由于until x.last
条件,如果所有值都是nil那么map函数应该返回一个空数组?
这应该是什么条件。
输出应为
[['a'],['b','nil','c'],[]]
请记住,我只想删除不在其中的尾随nil
值。
答案 0 :(得分:12)
为此,您可以忘记外部数组并仅为内部数组求解,然后使用map
将解决方案应用于所有数组。
drop_while
将返回一个新数组,但所有前导项都不符合某些条件(例如nil?
)。您想要跟踪,但请与reverse
结合使用。
[nil,nil,5,nil,6,nil].reverse.drop_while(&:nil?).reverse
[nil, nil, 5, nil, 6]
然后对所有数组使用map。
arr = [["a", nil, nil, nil], ["b", nil, "c", nil], [nil, nil, nil, nil]]
arr.map{|a| a.reverse.drop_while(&:nil?).reverse}
[["a"], ["b", nil, "c"], []]
如果您确实希望剩余的nil
实际上是一个字符串,您可以将它与执行您喜欢的任何此类转换的其他地图合并。
答案 1 :(得分:10)
你是正确的,但只是修改你的代码:
array.each { |e| e.pop until !e.last.nil? || e.empty? }
#=> [["a"], ["b", nil, "c"], []]
比使用reverse
- reverse
和drop_while
更快。
答案 2 :(得分:4)
另一个选择是使用rindex
:
arr.map do |e|
index = e.rindex { |i| !i.nil? } # the last index of not `nil` element
index ? e.first(index + 1) : e
end
#=> [["a"], ["b", nil, "c"], []]