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

时间:2021-01-19 20:23:44

I have an array something like this:

我有一个这样的数组:

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

I want to remove all trailing nil values from array in ruby.

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

I tried arr.map {|x| x.pop until x.last} but the problem with this approach is that when all the value of arrays are nil like in 3rd array in given array, the loop stucks.

我试着加勒比海盗。地图{ | | x。流行,直到x。最后一个}但是这种方法的问题是,当数组的所有值都为nil时,就像给定数组中的第3个数组一样,循环就会停止。

Because of the until x.last condition, If all the values are nil then the map function should return me an empty array?

因为直到x。最后一个条件,如果所有的值都为nil映射函数应该返回一个空数组?

What should be the conditions for this.

应该有什么条件。

The output should be

输出应该

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

Remember I just want to remove trailing nil values not in between.

记住,我只是想去掉后面的nil值。

3 个解决方案

#1


12  

For this you can forget about the outer array and solve it for just the inner arrays, then use map to apply the solution to all of them.

为此,您可以忘记外部数组,只对内部数组进行求解,然后使用map将解决方案应用到所有数组中。

drop_while will return a new array without all leading items that met some condition (e.g. nil?). You wanted trailing however so combine with reverse.

drop_while将返回一个新数组,其中没有满足某些条件的所有前置项(例如nil?)。你想要尾随但是,所以结合反向。

[nil,nil,5,nil,6,nil].reverse.drop_while(&:nil?).reverse
[nil, nil, 5, nil, 6]

Then use map for all the arrays.

然后对所有数组使用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"], []]

If you do want any remaining nil to actually be a string, you could combine it with another map performing any such conversion you like.

如果您确实希望任何剩余的nil实际上是一个字符串,您可以将它与执行任何您喜欢的转换的另一个映射结合起来。

#2


10  

You are on the right way, but just modify your code a bit:

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

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

It's faster than using reverse-reverse and drop_while.

它比使用反向反转和drop_while要快。

#3


4  

One more option is to use rindex:

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

#1


12  

For this you can forget about the outer array and solve it for just the inner arrays, then use map to apply the solution to all of them.

为此,您可以忘记外部数组,只对内部数组进行求解,然后使用map将解决方案应用到所有数组中。

drop_while will return a new array without all leading items that met some condition (e.g. nil?). You wanted trailing however so combine with reverse.

drop_while将返回一个新数组,其中没有满足某些条件的所有前置项(例如nil?)。你想要尾随但是,所以结合反向。

[nil,nil,5,nil,6,nil].reverse.drop_while(&:nil?).reverse
[nil, nil, 5, nil, 6]

Then use map for all the arrays.

然后对所有数组使用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"], []]

If you do want any remaining nil to actually be a string, you could combine it with another map performing any such conversion you like.

如果您确实希望任何剩余的nil实际上是一个字符串,您可以将它与执行任何您喜欢的转换的另一个映射结合起来。

#2


10  

You are on the right way, but just modify your code a bit:

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

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

It's faster than using reverse-reverse and drop_while.

它比使用反向反转和drop_while要快。

#3


4  

One more option is to use rindex:

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