array.nil? when array having only multiple `nil` values - arrays

Consider an array having only one value nil
array = [nil]
Is there any better way to check whether an array is nil or not, like array.nil??
This works:
array == [nil]
But what if there are multiple nil values in the array?
array = [nil, nil, nil]
Below is the requirement:
array = [1, 2] if array.nil?
array.nil? should also give 'true' when array = [nil, nil, nil]

You can use Array#any? to check if the array contains at least one value that is not false or nil:
array = [1,2] unless array.any?
If array is allowed to contain false and you are interested only in nil then Array#any? needs a block:
array = [1,2] unless array.any?{|i| !i.nil?}
Update
As #mu-is-too-short suggests, a better version is:
array = [1,2] if array.all?(&:nil?)
It does exactly what you need: Enumerable#all? returns true if the block returns a true-ish value for all elements of the array.

One option is to uniquify your array and then do what you were already doing:
array.uniq == [nil]
So if array is any amount of nils it will be true. On the other hand:
array.nil?
Checks whether array itself is nil, which is not the same as an array containing nil elements.

One of possible ways is to remove nil values with .compact and check if the result is empty? .
array = [1, 2] if array.compact.empty?

Related

hackerrank question - use of proc in ruby

problem: Create a Proc p that will check whether a given array of elements are nil or not. Use .nil? to evaluate elements. Print 'true' if elements are nil, and 'false' if the elements has a value
Issue: I came up with below solution but its giving me only one value as true instead of checking for each value of array , please help in correcting below code:
Code:
def check_nill(array1)
p = Proc.new{ |num| num.nil?}
c = array1.any?(&p)
return c
end
array1 = [2,nil,8]
result = check_nill(array1)
puts "#{ result1 }"
Output: true
Create a Proc to check if a value is a nil or not.
my_proc = Proc.new { |num| num.nil? }
Iterate over the array using the above proc
array1 = [2,nil,8]
array1.map { |x| my_proc.call(x) }
You will get the below result
[false, true, false]
Your solution doesn't work because the method you're using, Array#any?, returns true if any of the values in the array is nil (due to your p). What I understood is that you want a solution that will return if each element is nil or not.
A possible solution is:
# You can create a Proc `p` that'll map an array to the results of `nil?`.
p = Proc.new { |ary| ary.map(&:nil?) }
# You can apply a Proc by using the method `call`, or by doing:
# p.([1, nil, 2])
# p[[1, nil, 2]]
p.call([1, nil, 2]) # => [false, true, false]

How to remove array elements where element's fields are NULL

array = [[1555,100],[nil,95],[1774,nil],[1889,255]]
What would be the best way to remove the 2nd and 3rd elements from array since they have NULL fields?
Expected output :
array = [[1555,100],[1889,255]]
arr = [[1555,100],[nil,95],[1774,nil],[1889,255]]
arr.reject { |a,b| (a && b).nil? }
#=> [[1555, 100], [1889, 255]]
And yet another option:
array.reject { |a| a.any?(&:nil?) }
It is very similar to Cary Swoveland's answer, but will work with arrays of any length and will remove [false, nil] as well.
Use .compact to remove nil elements from array of arrays
array.map(&:compact)
# array = [[1555,100], [95], [1774], [1889, 255]]
Edit
Use .reject! to remove sub arrays containing nil elements.
array.reject! { |e| e.any? nil }
# array = [[1555,100], [1889,255]]

What's the way to check if all the elements in an array are nil? [duplicate]

This question already has answers here:
How do I check if there's a nil set or not in an array?
(5 answers)
Closed 4 years ago.
I would like to know if there's anything except nil values in an array.
arr = [nil, nil, nil, nil] # => true
arr = [nil, 45, nil, nil] # => false
There could be any values of any types (not only 45).
Use the Enumerable#all? method:
p arr.all? { |x| x.nil? }
Or
p arr.all?(&:nil?)
As #Stefan suggested,
p arr.all?(NilClass) #works only for Ruby 2.5
you could do arr.compact.empty?, compact gets rid of all the nil for you
you could read here at ruby guides to find about all the methods on Array class
You can also use #any? method for array
[nil, 45].any?
=> true
[nil, nil].any?
=> false
From the documentation:
If the block is not given, Ruby adds an implicit block of {|obj| obj} (that is any? will return true if at least one of the collection members is not false or nil.
Note: This won't work if false boolean values are present.
[nil, false].any?
=> false # It should return `true`
Other options would be:
arr = [nil, nil, 45]
arr.count(nil) == arr.length
=> false
(arr - [nil]).empty?
=> false

How do I strip off nil elements from the end of an array if all my elements are nil?

I'm using Ruby 2.4. I want to strip off nil elements from the end of an array, so I'm using
row_data.pop until row_data.last
but if the array only contains nil elements, this seems to cause some kind of infinite loop because the call never returns. How do I account for the fact that the array might contain all nil elements?
Just add an extra check to see if the array is empty.
row_data.pop until row_data.last || row_data.empty?
You can use Array#rindex to obtain the right-most non-nil entry (or determine that every element in the array is nil).
def kill_nils_at_end(arr)
ndx = arr.rindex(&:itself)
ndx ? arr[0..ndx] : []
end
kill_nils_at_end [1,nil,1,nil,nil,nil]
#=> [1, nil, 1]
kill_nils_at_end [nil,nil,nil,nil,nil,nil]
#=> []
This does not mutate the original array. If you wish to modify the array in place, change the penultimate line to
arr.replace(ndx ? arr[0..ndx] : [])
Try this
Most readable
arr = arr.reverse.drop_while(&:nil?).reverse
Most efficient
arr.slice!(0..arr.rindex { |each| nil != each }.to_i)
If all nils are to be removed, try this:
[1, nil, 3, nil, nil].compact #= [1,3]
see Map and Remove nil values in Ruby

create two arrays based on what meet a condition and the diff

Lets suppose I've the follow array:
a = [1,2,3]
I want to split it in two arrays from it, one with items for which a condition is true, and other for which the same condition is false:
b, c = a.split_in_two_arrays_or_something_like_that {|x| x == 3}
#=> b = [3]
#=> c = [1,2]
How can I do that in ruby? I don't want to repeat code with something like:
b = a.reject {|x| x == 3}
c = a.reject {|x| x != 3}
Nor iterate over the array twice.
Is there some method that return me something different than the modified array? For example, delete_if will work if it would return the deleted elements, but the original array would've keeped the same, but it doesn't work that way.
Use Enumerable#partition to separate the elements in your array according to a condition. We define the condition in partition's block:
a = [1,2,3]
b, c = a.partition { |x| x == 3 } #=> [[3], [1, 2]]
b #=> [3]
c #=> [1, 2]
This method creates an array with two subarrays.
The first subarray contains the values for which partition's block returns true.
The second subarray contains the values for which partition's block returns false.
Finally we apply parallel-assignment to assign variables b to the first subarray and c to the second.

Resources