Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cleaning Arrays of Arrays which consist of nils

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]} 
like image 499
StanisLove Sid Avatar asked Dec 15 '22 02:12

StanisLove Sid


2 Answers

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 nils. 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 nils.

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]]
like image 165
Dbz Avatar answered Jan 01 '23 18:01

Dbz


Assuming you're only interested in 2D-Arrays then:

Rid sub-arrays consisting of only nils:

arr.reject { |arr| arr.all?(&:nil?) }

Rid sub-arrays consisting of any nils:

arr.reject { |arr| arr.any?(&:nil?) }
like image 29
Sagar Pandya Avatar answered Jan 01 '23 18:01

Sagar Pandya