3

In ruby, is there a more concise way of expressing multiple OR conditions in an if statement?

For example this is the code I have:

if call_type == "GPRS" || call_type == "SMS" || call_type == "MMS" || call_type == "USSD" || call_type == "TELEPHONY"
  #do something
end

There will be more OR conditions and I don't want to write like this multiple times. Is there a better way to express this in ruby 2.1.0 ?

Thanks in advance.

Rakesh Jha
  • 125
  • 2
  • 9

1 Answers1

12

You could use Array#include?:

if %w(GPRS SMS MMS USSD TELEPHONY).include? call_type
  # ...
end

Or a case expression:

case call_type
when 'GPRS', 'SMS', 'MMS', 'USSD', 'TELEPHONY'
  # ...
end

Or a regular expression:

if call_type =~ /^(GPRS|SMS|MMS|USSD|TELEPHONY)$/
  # ...
end

As noted by cremno, ^ and $ match beginning and end of line. You can use \A and \z instead if call_type contains multiple lines.

Community
  • 1
  • 1
Stefan
  • 109,145
  • 14
  • 143
  • 218
  • 1
    You might want to use `\A`/`\z` (beginning/end of string) instead of `^`/`$` (beginning/end of line) to have the same behavior as your other examples (which don't accept `"ABC\nSMS"`, for example). – cremno Feb 24 '15 at 08:51
  • 1
    If `arr = %w{ a b c }` you can write `case('b'); when *arr; puts 'hi'; end #=> "hi"` and `r = Regexp.new('^('+arr.join('|')+')$') #=> /^(a|b|c)$/; 'b'[r] #=> "b"; 'd'[r] #=> nil`. This is convenient when `arr` is large. – Cary Swoveland Feb 24 '15 at 19:14
  • Your last comment is interesting. I would have thought `/^#{Regexp.union(arr).to_s}$/` (which works) would have been required, but `to_s` is not needed. Why? – Cary Swoveland Feb 27 '15 at 03:29