【问题标题】:Remove trailing nil values from array in ruby从 ruby​​ 中的数组中删除尾随 nil 值
【发布时间】:2017-08-24 11:47:21
【问题描述】:

我有一个类似这样的数组:

[["a", nil, nil, nil], ["b", nil, "c", nil], [nil, nil, nil, nil]]

我想从 ruby​​ 的数组中删除所有尾随的 nil 值。

我尝试了arr.map {|x| x.pop until x.last},但这种方法的问题在于,当数组的所有值都为零时,就像给定数组中的第三个数组一样,循环卡住了。

由于until x.last 条件,如果所有值都为零,那么map 函数应该返回一个空数组吗?

这应该是什么条件。

输出应该是

[['a'],['b','nil','c'],[]]

请记住,我只想删除不在两者之间的尾随 nil 值。

【问题讨论】:

  • 真的应该将nil 之间的值转换为'nil' 字符串吗?

标签: ruby-on-rails arrays ruby


【解决方案1】:

为此,您可以忘记外部数组并仅解决内部数组,然后使用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 实际上是一个字符串,您可以将它与另一个执行您喜欢的任何此类转换的映射结合起来。

【讨论】:

    【解决方案2】:

    您的方法是正确的,但只需稍微修改您的代码:

    array.each { |e| e.pop until !e.last.nil? || e.empty? }
    #=> [["a"], ["b", nil, "c"], []]
    

    比使用reverse-reversedrop_while 更快。

    【讨论】:

    • 我想关键是是否需要改变原件。尽管复制 + 弹出可能仍然更快,但确实如此。
    【解决方案3】:

    另一种选择是使用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"], []]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-12
      • 2020-08-09
      相关资源
      最近更新 更多