ruby - 当我遵循 Ruby rubocop 样式指南并使用 .zero 时方法失败?而不是 == 0
问题描述
我正在尝试用 Ruby 完成一个编码练习,如下所示:
TODO:从一个整数数组开始,返回一个包含整数和 'Fizz'、'Buzz' 或 'FizzBuzz' 的数组
编写一个方法
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
解决方案
现在我们看到了失败的代码,这就是它失败的原因:
你有一个数组a
,我想你打算包含结果。您在其前面加上数字,并修复需要说“Fizz”或“Buzz”或“FizzBuzz”的数字。这会起作用,但是对于一个严重的失败:您在 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?
不是一件事。
推荐阅读
- laravel - 如何在路由之前获取一些数据并将其发送到 laravel 中的路由?
- flutter - 找不到正确的提供者
在此 EditRetailer 小部件上方 - android - 是否可以在编译开始之前知道 LOCAL_SRC_FILES 的值?
- python - DataFrame.info() 与 DataFrame.Series.describe() 不同
- swift - Xcode11,TableView 单元格选择样式不起作用
- angular - 无法绑定到“rangePicker”,因为它不是“mat-date-range-input”的已知属性
- azure-storage - Microsoft.Azure.Storage.Blob v11.1.7 在创建 Queueclient 时抛出异常
- javascript - ngBootstrap typeahead 对象作为输入值
- javascript - 复选框按类型过滤 - ReactJS
- django - Django 查询集过滤掉具有共同成员的对象