Ruby if else in array.each
Solution 1
The syntax of a conditional expression in Ruby is:
if c_1 then e_1 elsif c_2 then e_2 elsif c_3 then e_3 … elsif c_n then e_n else e_nplus1 end
where c_1
… c_n
and e_1
… e_nplus1
can be arbitrary Ruby expressions.
It is possible to use an expression separator (i.e. ;
or newline) instead of the then
keyword to separate the parts of the conditional expression.
With semicolon (this usage is non-idiomatic):
if c_1; e_1 elsif c_2; e_2 elsif c_3; e_3 … elsif c_n; e_n else e_nplus1 end
With newlines:
if c_1
e_1
elsif c_2
e_2
elsif c_3
e_3
# …
elsif c_n
e_n
else
e_nplus1
end
If you use newlines, you can optionally also use the then
keyword, but that is non-idiomatic, too:
if c_1
then e_1
elsif c_2
then e_2
elsif c_3
then e_3
# …
elsif c_n
then e_n
else
e_nplus1
end
So, in your case, the correct syntax would be:
# idiomatic
a.each { |i| if i % 3 == 0 then puts "three" elsif i % 5 == 0 then puts "five" else puts i end }
# non-idiomatic
a.each { |i| if i % 3 == 0; puts "three" elsif i % 5 == 0; puts "five" else puts i end }
# idiomatic
a.each { |i|
if i % 3 == 0
puts "three"
elsif i % 5 == 0
puts "five"
else
puts i
end
}
# non-idiomatic
a.each { |i|
if i % 3 == 0
then puts "three"
elsif i % 5 == 0
then puts "five"
else
puts i
end
}
However, for such a chain of if
/ elsif
, it is typically more idiomatic to use a case
expression:
# idiomatic
case when c_1 then e_1 when c_2 then e_2 when c_3 then e_3 … when c_n then e_n else e_nplus1 end
# non-idiomatic
case when c_1; e_1 when c_2; e_2 when c_3; e_3 … when c_n; e_n else e_nplus1 end
# idiomatic
case
when c_1
e_1
when c_2
e_2
when c_3
e_3
# …
when c_n
e_n
else
e_nplus1
end
# non-idiomatic
case
when c_1
then e_1
when c_2
then e_2
when c_3
then e_3
# …
when c_n
then e_n
else
e_nplus1
end
Which in your case would look like this:
# idiomatic
a.each { |i| case when i % 3 == 0 then puts "three" when i % 5 == 0 then puts "five" else puts i end }
# non-idiomatic
a.each { |i| case when i % 3 == 0; puts "three" when i % 5 == 0; puts "five" else puts i end }
# idiomatic
a.each { |i|
case
when i % 3 == 0
puts "three"
when i % 5 == 0
puts "five"
else
puts i
end
}
# non-idiomatic
a.each { |i|
case
when i % 3 == 0
then puts "three"
when i % 5 == 0
then puts "five"
else
puts i
end
}
Note that the conditional expressions (both if
and case
) are expressions, not statements. There are no statements in Ruby, everything is an expression, everything evaluates to a value. A conditional expression evaluates to the value of the expression in the branch that was taken.
So, you could also write it like this:
# idiomatic
a.each { |i| puts(if i % 3 == 0 then "three" elsif i % 5 == 0 then "five" else i end) }
# non-idiomatic
a.each { |i| puts(if i % 3 == 0; "three" elsif i % 5 == 0; "five" else i end) }
# idiomatic
a.each { |i|
puts(if i % 3 == 0
"three"
elsif i % 5 == 0
"five"
else
i
end)
}
# non-idiomatic
a.each { |i|
puts(if i % 3 == 0
then "three"
elsif i % 5 == 0
then "five"
else
i
end)
}
# idiomatic
a.each { |i| puts(case when i % 3 == 0 then "three" when i % 5 == 0 then "five" else i end) }
# non-idiomatic
a.each { |i| puts(case when i % 3 == 0; "three" when i % 5 == 0; "five" else i end) }
# idiomatic
a.each { |i|
puts(case
when i % 3 == 0
"three"
when i % 5 == 0
"five"
else
i
end)
}
# non-idiomatic
a.each { |i|
puts(case
when i % 3 == 0
then "three"
when i % 5 == 0
then "five"
else
i
end)
}
Solution 2
Here is the syntax.
a = *(1..100)
a.each do |i|
if i % 3 == 0
puts "three"
elsif i % 5 == 0
puts "five"
else
puts i
end
end
Keep in mind that each
will return Enumerator
, but not exact value. You need to use return
keyword to return value.
Here is the docs
Solution 3
You can use an if
to qualify a single statement, but once you move into elsif/else
territory, it's necessary to break it up like a normal C-style if
statement:
a.each do |i|
if i % 3 == 0
puts "three"
elsif i % 5 == 0
puts "five"
else
puts i
end
end
Solution 4
Please see if the below code helps
def abc
a = *(1..100)
a.each do |i|
if i % 3 == 0
puts "three"
elsif i % 5 == 0
puts "five"
else
puts i
end
end
end
=> :abc
2.3.0 :013 > abc
this gives the desired output in irb mode.
Solution 5
Or, if you want to emphasize, that there is always a puts
and just the output value changes:
puts(
if i%3==0
'three'
elsif i%5==0
'five'
else
i
end
)
Mike
Updated on June 04, 2022Comments
-
Mike almost 2 years
New to Ruby here. I am attempting to put an if else statement in an array to send a string if a certain modulus == 0. for the life of me i can't find it anywhere. I am sure someone will find it ridiculously simple.
a = *(1..100) a.each { |i| puts "three" if i % 3 == 0 elsif puts "five" if i % 5 == 0 else puts i}
Just not sure of the correct syntax. Still new to ruby and am trying to learn the syntax. Took a C class last semester and my brain keeps wanting to put in C syntax.
When I leave it as
a = *(1..100) a.each { |i| puts "three" if i % 3 == 0}
it works fine, just trying to figure out how to add if else to it. Help is appreciated.
The answers below were really helpful. I am trying to take it a step further and call it into a function. It keeps returning 5, and not "five", or 3, and not "three".
here is my function:
def array_mod a = *(1..100) a.each { |i| if i % 3 == 0 && i % 5 == 0; i = "fifteen" elsif i % 3 == 0; i = "three" elsif i % 5 == 0; i = "five" else i = i end }
end
and here is my attempt at calling it.
require "minitest/autorun" require_relative "array_modulus.rb" class TestArrayFunction < Minitest::Test def test_array1 results = array_mod assert_equal(100, results.length) end def test_array2 results = array_mod assert_equal("three", results[2]) end end
I was told it is not updating my array. Thanks again.
-
fl00r over 7 years
Keep in mind that each will return Enumerator, but not exact value
what do you mean? -
Mike over 7 yearsok. I didn't know if I had to put an else inside the brackets. I am used to C's using parentheses and curled brackets for everything. Ruby hardly uses them from what ive seen so far. But the |i| , is that labeling the following code as "i"? Or is it a temporary labelling i for that block? Thanks though, this is exactly what I was curious about.
-
mwp over 7 years@Mike I'm not sure you mean by "inside the brackets." The
else
is lined up with theif
, just like it would be in C (minus the curly braces). Yeah, curlies aren't used the same way... they're used to define blocks in Ruby (similar todo
..end
). The|i|
is just declaring the loop variable(s); each time through the loop,i
will be set to the next element ofa
. -
Mike over 7 yearsYour reply was extremely helpful. I tried to ask a second question in this box but i guess they don't want you posting code in these boxes, so I updated my top question. Thanks again man.
-
Jörg W Mittag over 7 yearsThat's because when you have a question, you should write a question, not a comment ;-)
-
retgoat over 7 yearsI meant that
each
will return unchanged array in that case.