8

If I set some nil values to an array, I don't seem to be able to check for them. I have tried any? and empty?.

array = [nil, nil, nil]
#=> [nil, nil, nil]

array[1].any?
#=> "NoMethodError: undefined method `any?' for nil:NilClass"

6 Answers 6

18

any? iterates over a container, like an array, and looks at each element passed to it to see if it passes a test. If one does, the loop stops and true is returned:

ary = [nil, 1]

ary.any?{ |e| e.nil? } # => true

The documentation explains this well:

Passes each element of the collection to the given block. The method returns true if the block ever returns a value other than false or nil. If the block is not given, Ruby adds an implicit block of { |obj| obj } that will cause any? to return true if at least one of the collection members is not false or nil.

%w[ant bear cat].any? { |word| word.length >= 3 } #=> true
%w[ant bear cat].any? { |word| word.length >= 4 } #=> true
[nil, true, 99].any?                              #=> true

any? is one of a number of tests that can be applied to an array to determine if there are none?, any?, one?, or all?.

ary.one?{ |e| e == 1 } # => true
ary.none?{ |e| e == 2 } # => true
ary.all? { |e| e.nil? } # => false

Your code fails because you're trying to use a non-existing any? method for a nil value, hence the error you got: "NoMethodError: undefined method `any?' for nil:NilClass"

ary[0] # => nil
ary.first # => nil
ary.first.respond_to?(:'any?') # => false

You have to pay attention to what you're doing. ary[0] or array.first returns the element at that array index, not an array.

empty? only checks to see if the container has elements in it. In other words, does it have a size > 0?

ary.empty? # => false
ary.size == 0 # => false
ary.size > 0 # => true
[].empty? # => true
[].size == 0 # => true
[].size > 0 # => false
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! args.any?(&:nil?) look better for me.
11

If you want to check if the array includes nil:

[nil, 1, 2].include?(nil) #=> true

1 Comment

Sometimes the best approach is the simplest approach, as EVERYONE will get the intent immediately when they look at the code. Particularly if it's me coming back to it. I don't want another "Why does that work again?" moment. Have enough already. This should be marked as the best answer.
9

any?'s default bahavior is to check for ant truthy value in the array.

# check if there are any truthy values in the array
[nil, nil, nil].any? #=> false
[nil, true, nil].any? #=> true

# check if all values are truthy
[true,Duck.new,2,'yes'].all? #=> true
[nil, false].all? #=> false

# check if none values are truthy
[nil,false,nil].none? #=> true
[Math::PI,nil,false].none? #=> false

All this methods accepts an optional block to customize the value beingchecked, which comes very handy in your specific use case:

[false, false, false].any?(&:nil?) => false
[false, false, nil].any?(&:nil?) => true

1 Comment

Numbers is only concerned with nil, not nil or false.
2
array = [nil, nil, nil]
#=> [nil, nil, nil]
array[1].nil?
#=> true

Comments

2

You can turn nil values into booleans this way to check for them

array = [nil, nil, nil]
#=> [nil, nil, nil]
!array[1]
#=> true
!!array[1]
#=>false

However, using any? checks for the existence of something. You can use

array.any? {|item| !item }
#=> true

To check if there are any values that evaluate to false as a nil value does. Be careful if you might have a false value in your array though because it will also be evaluated as true using this this method.

Or you could just use:

array.any? { |item| item.nil? }

As other posters have suggested

Your problem is that you are calling the any? method on nil and not on an array.

2 Comments

Numbers is only concerned with nil, not nil or false.
You're right, thats why I added the bit about nil as well :)
0

If you are checking that does the whole array contains nil than you can use any?

array = [nil, nil, nil]
#=> [nil, nil, nil]

array.any?
#=> false

false means that array does not contains any actual value.

OR do the comparison using uniq

array.uniq == [nil]
#=> true

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.