How to check if a value exists in an array in Ruby
I have a value 'Dog'
and an array ['Cat', 'Dog', 'Bird']
.
How do I check if it exists in the array without looping through it? Is there a simple way of checking if the value exists, nothing more?
Solution 1:
You're looking for include?
:
>> ['Cat', 'Dog', 'Bird'].include? 'Dog'
=> true
Solution 2:
There is an in?
method in ActiveSupport
(part of Rails) since v3.1, as pointed out by @campaterson. So within Rails, or if you require 'active_support'
, you can write:
'Unicorn'.in?(['Cat', 'Dog', 'Bird']) # => false
OTOH, there is no in
operator or #in?
method in Ruby itself, even though it has been proposed before, in particular by Yusuke Endoh a top notch member of ruby-core.
As pointed out by others, the reverse method include?
exists, for all Enumerable
s including Array
, Hash
, Set
, Range
:
['Cat', 'Dog', 'Bird'].include?('Unicorn') # => false
Note that if you have many values in your array, they will all be checked one after the other (i.e. O(n)
), while that lookup for a hash will be constant time (i.e O(1)
). So if you array is constant, for example, it is a good idea to use a Set instead. E.g:
require 'set'
ALLOWED_METHODS = Set[:to_s, :to_i, :upcase, :downcase
# etc
]
def foo(what)
raise "Not allowed" unless ALLOWED_METHODS.include?(what.to_sym)
bar.send(what)
end
A quick test reveals that calling include?
on a 10 element Set
is about 3.5x faster than calling it on the equivalent Array
(if the element is not found).
A final closing note: be wary when using include?
on a Range
, there are subtleties, so refer to the doc and compare with cover?
...
Solution 3:
Try
['Cat', 'Dog', 'Bird'].include?('Dog')
Solution 4:
If you want to check by a block, you could try any?
or all?
.
%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
See Enumerable for more information.
My inspiration came from "evaluate if array has any items in ruby"