13

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.

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.

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

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.

1
  • 3
    Should in-between nil values really be converted to 'nil' strings? Commented Aug 24, 2017 at 15:02

3 Answers 3

14

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.

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.

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

Then use map for all the arrays.

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.

Sign up to request clarification or add additional context in comments.

Comments

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.

1 Comment

I guess the key point is if mutating the original is desired or not. Allthough a copy + pop might still be faster, true.
4

One more option is to use 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"], []]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.