Test if variable matches any of several strings w/o long if-elsif chain, or case-when
Perhaps you didn't know that you can put multiple conditions on a single case:
case mystr
when "abc", "def", "ghi", "xyz"
..
end
But for this specific string-based test, I would use regex:
if mystr =~ /\A(?:abc|def|ghi|xyz)\z/
If you don't want to construct a regex, and you don't want a case
statement, you can create an array of objects and use Array#include?
test to see if the object is in the array:
if [a,b,c,d].include?( o )
or, by monkey-patching Object, you can even turn it around:
class Object
def in?( *values )
values.include?( self )
end
end
if o.in?( a, b, c, d )
ruby - How to do if X is equal to either one of these values (xxx,eeee,yyyy,dadadad)
Use a regular expression:
do_x if file_ext =~ /\A(doc|xls|ppt)\Z/
Or, if you have a large enough list of things that writing a regex feels impractical, you could do something like
file_extensions = %w(xls csv doc txt odf jpg png blah blah blah blah blah)
do_x if file_extensions.include?(file_ext)
Of course there is always the option of testing each value individually:
do_x if file_ext == "doc" || file_ext == "xls" || ... || file_ext == "zzz"
In Ruby, how do I find out if a string is not in an array?
do_this unless ["www", "blog", "foo", "bar"].include?(current_subdomain)
or
do_this if not ["www", "blog", "foo", "bar"].include?(current_subdomain)
I'm using the Array#include? method.
However using unless
is a fairly big ruby idiom.
Why doesn't my if/elsif statement create tagged links and send them to different routes?
If you use if/else statements, you want to ask a question and perform one or the other based on the answer. It's called a conditional statement because you want a condition to be met before providing an action. Only after the answer is given you tell what to do next.
Now, what you are doing is the opposite. You tell what to do, without ever asking the question when to do it. No wonder it only runs the if statement, since this statement always returns true. The problem you face is that your first condition can never be false or nil.
As a rule of thumb, a question/condition should always have multiple possible answers, otherwise there is no point in asking.
Ruby case statements with multiple variables
This is a simplistic way to add ===
:
class Array
def ===(other)
return false if (other.size != self.size)
other_dup = other.dup
all? do |e|
e === other_dup.shift
end
end
end
[
['foo', 3],
%w[ foo bar ],
%w[ one ],
[]
].each do |ary|
ary_type = case ary
when [String, Fixnum] then "[String, Fixnum]"
when [String, String] then "[String, String]"
when [String] then "[String]"
else
"no match"
end
puts ary_type
end
# >> [String, Fixnum]
# >> [String, String]
# >> [String]
# >> no match
How to write a switch statement in Ruby
Ruby uses the case
expression instead.
case x
when 1..5
"It's between 1 and 5"
when 6
"It's 6"
when "foo", "bar"
"It's either foo or bar"
when String
"You passed a string"
else
"You gave me #{x} -- I have no idea what to do with that."
end
Ruby compares the object in the when
clause with the object in the case
clause using the ===
operator. For example, 1..5 === x
, and not x === 1..5
.
This allows for sophisticated when
clauses as seen above. Ranges, classes and all sorts of things can be tested for rather than just equality.
Unlike switch
statements in many other languages, Ruby’s case
does not have fall-through, so there is no need to end each when
with a break
. You can also specify multiple matches in a single when
clause like when "foo", "bar"
.
Related Topics
How to Run All Tests With Minitest
Rake "Already Initialized Constant Wfkv_" Warning
"Gem Install Rails" Fails With Dns Error
Launching Background Process in Capistrano Task
Rails Assets:Precompile Yarn Executable Was Not Detected in the System
Validation Failed: Upload File Has an Extension That Does Not Match Its Contents
Total Newbie: Instance Variables in Ruby
Ruby: What Does the Comment "Frozen_String_Literal: True" Do
How to Understand the Difference Between Class_Eval() and Instance_Eval()
Idiomatic Object Creation in Ruby
Ruby - Access Multidimensional Hash and Avoid Access Nil Object
How to Save a Base64 String as an Image Using Ruby
Nokogiri Will Not Install - Error: Failed to Build Gem Native Extension