包含从1到N的数字的数组
我试图返回一个包含数字从1
到N的数组,其中N永远不会小于1
,并具有以下条件:
3
的倍数:则改为使用值'Fizz'
。 5
的倍数:请改为使用值'Buzz'
。 3
和5
的倍数:则改为使用值'FizzBuzz'
。 这就是我现在所拥有的。 我正朝着正确的方向走吗?
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
在这么短的一段代码中,你有很多重要的错误和坏习惯。
{
未关闭。 [1..n]
。 map
创建一个数组,但不知何故,你对它没有做任何事情,而是在puts
原始对象。 这没有意义。 (i % 3 == 0 && i % 5 == 0)
条件放在开头,或者使用i % 5 != 0
和i % 3 != 0
条件,但不能同时使用这两个条件。 前者更聪明。 x
,链接很简单。 你应该做链接。 zero?
可以使用的方法。 do
... end
而不是{
... }
在Rubyists中非常普遍。 十三行中的四个错误非常多。 一个更正的代码将是:
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)
你在正确的方向。 最大的问题是数组定义。 下列:
x = [1..n]
...将创建一个具有单个值的数组 - 一个1..n
范围对象。
任何这些都是有效的选择:
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
正如@sawa指出的那样,其他重大问题是一个未关闭的括号和使用map
而不是map!
(或者,使用x = x.map { … }
或者简单地返回x.map { … }
, puts
x.map { … }
到函数之外)。
一些代码优化,它只是萨瓦答案的附加部分:
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"]
注释:
n
维。 v.empty? && i || v
v.empty? && i || v
v.empty? && i || v
可以用v.empty? ? i : v
替换v.empty? ? i : v
v.empty? ? i : v
v.empty? ? i : v
,但这是一个口味。 我更喜欢&& ||
对。