For example I have an array:
[[nil, nil], [1, 2], [nil, nil], [nil, nil]]
What is the best way to clean it? Array must have only arrays which do not consist of nil. After cleaning it has to be:
[[1,2]]
Something like:
[[nil, nil], [1, 2], [nil, nil], [nil, nil]].each {|x| x - [nil]}
The methods on arrays that remove nil
elements is called compact. However, that is not quite enough for this situation because you have an array of arrays. In addition you will want to select the non-nil arrays, or reject the arrays that are nil
. You can easily combine the two in the following way:
[[nil, nil], [1, 2], [nil, nil], [nil, nil]].reject { |arr| arr.compact.empty? }
This will only work if you have sub arrays of numbers OR nil
s. If your sub arrays contain both e.g. [1, nil, 2]
, then this solution will keep the entire sub array.
It is possible to mutate the sub array to remove nil
while you iterate over the sub arrays, but it can be considered practice to mutate while you iterate. Nevertheless, the way to do this would be to use the bang version of the compact
method which mutates the original object:
.reject { |arr| arr.compact!.empty? }
This will take [[1, 2, nil, 3]]
and return [[1, 2, 3]]
.
As sagarpandya82 pointed out, you can also use the all or any? methods for simply checking if everything is nil
, or if anything is nil
instead of removing the nil
s.
To recap:
original_array = [[nil, nil],[1, nil, 2], [1, 2, 3]]
original_array.reject { |arr| arr.all?(:nil) } # returns [[1, nil, 2], [1, 2, 3]]
original_array.reject { |arr| arr.compact.empty? } # returns [[1, nil, 2], [1, 2, 3]]
original_array.reject { |arr| arr.any?(:nil) } # returns [[1, 2, 3]]
original_array.reject { |arr| arr.compact!.empty? } # returns [[1, 2, 3], [1, 2]]
Assuming you're only interested in 2D-Arrays then:
Rid sub-arrays consisting of only nil
s:
arr.reject { |arr| arr.all?(&:nil?) }
Rid sub-arrays consisting of any nil
s:
arr.reject { |arr| arr.any?(&:nil?) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With