包含从1到N的数字的数组

时间:2014-04-26 11:40:07

标签: ruby arrays

我正在尝试返回一个包含1到N的数字的数组,其中N永远不会小于1,具有以下条件:

  • 如果该值是3的倍数:请改为使用值'Fizz'
  • 如果该值是5的倍数:请改为使用值'Buzz'
  • 如果该值是35的倍数:请改为使用值'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

4 个答案:

答案 0 :(得分:4)

在这么短的代码中,你有很多重要的错误和坏习惯。

  1. [错误] 您的{未关闭。
  2. [错误] 您的对象[1..n]错误。
  3. [错误] 您正在尝试使用map创建数组,但不知何故,您没有对其进行任何操作,而是在原始对象上执行puts 。这毫无意义。
  4. [错误] 当两种条件都不满足时,您没有给出合适的值。
  5. [重构] 您的情况多余。您只需将(i % 3 == 0 && i % 5 == 0)条件置于开头,或使用i % 5 != 0i % 3 != 0条件,但不能同时使用两者。前者更聪明。
  6. [重构] 您只使用x一次,链接很容易。你应该做链接。
  7. [重构] 您可以使用zero?方法。
  8. [重构] 您有一些不必要的括号。
  9. [样式] 由于条件值足够短,您可以将它们放在一行中。
  10. [样式] 在Rubyists中建立使用do ... end而不是{ ...... }当块超过一行时。
  11. 十三行中有四个错误。更正后的代码为:

    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)
    

答案 1 :(得分:1)

你的方向正确。最大的问题是数组定义。以下内容:

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 { … }或只返回{{1并将x.map { … }移到函数之外。)

答案 2 :(得分:0)

一些代码优化,它只是sawa的答案的补充:

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"] 

评论:

  1. 使用n维创建一个填充空字符串的新数组。
  2. 由于索引从1开始,在循环中递增为1。
  3. 使用三个条件,我们为数组中的每个条件设置一个适当的新值。
  4. v.empty? && i || v可以替换为v.empty? ? i : v,但这是为了品味。我更喜欢&& ||对。

答案 3 :(得分:-1)

def fizzbuzz(n)
  [*1..n].each { |i|
      if i % 3 == 0 && i % 5 == 0
         'FizzBuzz'
      elsif  i % 3 == 0 
         'Fizz'
      elsif i % 5 == 0
         'Buzz'
      end
   }
end

您也可以使用案例陈述:

[*1..16].each { |i|
  case 
  when (i % 3).zero? && (i % 5).zero?
      ‘FizzBuzz'
  when  (i % 3).zero?
      'Fizz'
  when (i % 5).zero?
      'Buzz'
  end
}