首页 > 解决方案 > 当我遵循 Ruby rubocop 样式指南并使用 .zero 时方法失败?而不是 == 0

问题描述

我正在尝试用 Ruby 完成一个编码练习,如下所示:

TODO:从一个整数数组开始,返回一个包含整数和 'Fizz'、'Buzz' 或 'FizzBu​​zz' 的数组

编写一个方法fizz_buzz,它以 anumber作为参数,并返回一个number从 1 到 的元素数组number,但根据以下规则替换其中的一些元素:

  • 如果该数能被 整除3,则将其替换为'Fizz'
  • 如果该数能被 整除5,则将其替换为'Buzz'
  • 3如果数字可以被和整除5,则将其替换为'FizzBuzz'Write

如果我遵循 a rubocop style guide,我们在完成任务后被要求使用它,并且按照指示,使用.zero而不是== 0?我的方法失败,我不明白为什么。

我现在失败的解决方案是我的风格指南要求的编辑:

def fizz_buzz(number)
  fail ArgumentError, "#{number} is less than 1" if number < 1
  a = [number]
  while number > 1
    number = number - 1
    a.unshift(number)
    a.map! { |x| (x % 15).zero? ? 'FizzBuzz' : x }
    a.map! { |x| (x % 3).zero? ? 'Fizz' : x }
    a.map! { |x| (x % 5).zero? ? 'Buzz' : x }
  end
  a
end

  should return the array [ 1, 2, 'Fizz' ] for number 3 (FAILED - 1)
  should return the array [ 1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7 ] for number 7 (FAILED - 2)
  should return an array with 'FizzBuzz' at the 15th element of the array (15 is divisible by both 3 and 5) (FAILED - 3)

失败:

  1) fizz_buzz should return the array [ 1, 2, 'Fizz' ] for number 3
     Failure/Error: a.map! { |x| (x % 5).zero? ? 'Buzz' : x }

 NoMethodError:
   undefined method `zero?' for "Fizz":String
 # ./lib/fizz_buzz.rb:12:in `block in fizz_buzz'
 # ./lib/fizz_buzz.rb:12:in `map!'
 # ./lib/fizz_buzz.rb:12:in `fizz_buzz'
 # ./spec/fizz_buzz_spec.rb:13:in `block (2 levels) in <top (required)>'

  2) fizz_buzz should return the array [ 1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7 ] for number 7
     Failure/Error: a.map! { |x| (x % 5).zero? ? 'Buzz' : x }

 NoMethodError:
   undefined method `zero?' for "Fizz":String
 # ./lib/fizz_buzz.rb:12:in `block in fizz_buzz'
 # ./lib/fizz_buzz.rb:12:in `map!'
 # ./lib/fizz_buzz.rb:12:in `fizz_buzz'
 # ./spec/fizz_buzz_spec.rb:17:in `block (2 levels) in <top (required)>'

  3) fizz_buzz should return an array with 'FizzBuzz' at the 15th element of the array (15 is divisible by both 3 and 5)
     Failure/Error: a.map! { |x| (x % 5).zero? ? 'Buzz' : x }

 NoMethodError:
   undefined method `zero?' for "Fizz":String
 # ./lib/fizz_buzz.rb:12:in `block in fizz_buzz'
 # ./lib/fizz_buzz.rb:12:in `map!'
 # ./lib/fizz_buzz.rb:12:in `fizz_buzz'
 # ./spec/fizz_buzz_spec.rb:21:in `block (2 levels) in <top (required)>'

我的工作解决方案未能通过样式指南:

def fizz_buzz(number)
  fail ArgumentError, "#{number} is less than 1" if number < 1
  a = [number]
  while number > 1
    number = number - 1
    a.unshift(number)
    a.map! { |x| (x % 15) == 0 ? 'FizzBuzz' : x }
    a.map! { |x| (x % 3) == 0 ? 'Fizz' : x }
    a.map! { |x| (x % 5) == 0 ? 'Buzz' : x }
  end
  a
end

与分配的任务一起提供的解决方案:

# def fizz_buzz(number)
#   fail ArgumentError, "#{number} should be greater than 1" if number < 1
#   (1..number).map do |i|
#     if (i % 3).zero? && (i % 5).zero?
#       'FizzBuzz'
#     elsif (i % 3).zero?
#       'Fizz'
#     elsif (i % 5).zero?
#       'Buzz'
#     else
#       i
#     end
#   end
# end

标签: rubyfizzbuzz

解决方案


现在我们看到了失败的代码,这就是它失败的原因:

你有一个数组a,我想你打算包含结果。您在其前面加上数字,并修复需要说“Fizz”或“Buzz”或“FizzBu​​zz”的数字。这会起作用,但是对于一个严重的失败:您在 loop 的每次迭代中处理数组。如果你只修过一次,就在你退货之前,那就没问题了。但是,这样,会发生什么(例如对于输入值4):

  • 你开始你的阵列4
  • 您运行修复程序,但4很好,不需要修复
  • 你前置3
  • 您运行修复程序;数组现在是["Fizz", 4]. 到现在为止还挺好。
  • 你在前面加上2; 数组是[2, "Fizz", 4]
  • 您运行修复程序。2在没有干预的情况下通过,然后"Fizz"轮到 。
  • "Fizz"不是数字,因此您不调用Number#%余数运算符,而是调用String#%格式化运算符。string 中没有格式符号"Fizz",因此格式化运算符没有做任何有趣的事情并返回 string "Fizz"
  • 然后你测试它是否为零。当您尝试"Fizz" == 0时,它会是“Duh,no”并且刚刚返回false,因为所有类(以 开头BasicObject)都定义了#==. 但是"Fizz".zero?失败了,因为不像Number#zero?String#zero?不是一件事。

推荐阅读