Array containing numbers from 1 to N
I am trying to return an array containing the numbers from 1
to N, where N will never be less than 1
, with the following conditions:
3
: use the value 'Fizz'
instead. 5
: use the value 'Buzz'
instead. 3
and 5
: use the value 'FizzBuzz'
instead. This is what I have right now. Am I going in the right direction?
def fizzbuzz(n)
x = [1..n]
x.map { |i|
if (i % 3 == 0 && i % 5 == 0)
'FizzBuzz'
elsif (i % 3 == 0 && i % 5 != 0)
'Fizz'
elsif (i % 5 == 0 && i % 3 != 0)
'Buzz'
end
puts x
end
In such a short piece of code, you have so many crucial mistakes and bad habits.
{
is not closed. [1..n]
. map
, but somehow you are not doing anything with it, and are instead doing puts
on the original object. That is meaningless. (i % 3 == 0 && i % 5 == 0)
condition at the beginning, or use the i % 5 != 0
and i % 3 != 0
conditions, but not both. The former is smarter. x
only once, where chaining is easy. You should do chaining. zero?
method that you can use. do
... end
rather than {
... }
when the block exceeds a single line. Four bugs in thirteen lines is pretty much. A corrected code would be:
def fizzbuzz(n)
(1..n).map do |i|
if (i % 3).zero? && (i % 5).zero? then 'FizzBuzz'
elsif (i % 3).zero? then 'Fizz'
elsif (i % 5).zero? then 'Buzz'
else i
end
end
end
puts fizzbuzz(10)
You're in the right direction. The biggest issue is the array definition. The following:
x = [1..n]
… will create an array with a single value — a 1..n
range object.
Any of these are valid alternatives:
x = 1..n # no need for an array since you're using map
x = (1..n).to_a # converts the range to an array explicitly
x = [*1..n] # unsplats the range
The other big issues, as point out by @sawa, are an unclosed bracket and the use of map
instead of map!
(alternatively, use x = x.map { … }
or simply return x.map { … }
and move puts
outside of the function).
Some code optimization, it is just additionals to sawa's answer:
def fizzbuzz(n)
x = Array.new(n) { '' }.map.with_index(1) do |v,i|
v << 'Fizz' if (i % 3).zero?
v << 'Buzz' if (i % 5).zero?
v.empty? && i || v
end
end
fizzbuzz(15)
# => [1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "FizzBuzz"]
Comments:
n
th dimension. v.empty? && i || v
v.empty? && i || v
v.empty? && i || v
can be replace with v.empty? ? i : v
v.empty? ? i : v
v.empty? ? i : v
, but it is for a taste. I prefer && ||
pair. 上一篇: FizzBuzz不会使用case / when发出嘶嘶声或嗡嗡声
下一篇: 包含从1到N的数字的数组