Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove trailing nil values from array in ruby

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.

like image 236
Ashish Jambhulkar Avatar asked Aug 24 '17 11:08

Ashish Jambhulkar


People also ask

How do you remove nil values in array using Ruby?

Syntax: Array. compact() Parameter: Array to remove the 'nil' value from. Return: removes all the nil values from the array.

What does compact do in Ruby?

The compact method in Ruby returns an array that contains non-nil elements. This means that when we call this method on an array that contains nil elements, it removes them. It only returns the other, non-nil, elements of the array.

Is nil a Ruby?

Well, nil is a special Ruby object used to represent an “empty” or “default” value. It's also a “falsy” value, meaning that it behaves like false when used in a conditional statement. Now: There is ONLY one nil object, with an object_id of 4 (or 8 in 64-bit Ruby), this is part of why nil is special.


1 Answers

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.

like image 181
Fire Lancer Avatar answered Sep 26 '22 04:09

Fire Lancer