从ruby中的数组中删除尾随的nil值

时间:2017-08-24 11:47:22

标签: ruby-on-rails arrays ruby

我有一个像这样的数组:

[["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值。

3 个答案:

答案 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 - reversedrop_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"], []]
相关问题