Ruby中使用Enumerable实现FizzBuzz时如何提取内联计算?
问题分析
你的问题核心是全局变量只会在定义时计算一次,而非遍历每个元素时动态更新。提前定义$div_1和$div_2时,numb还未被赋值(运行代码会直接报错,因为numb是未定义的局部变量);就算强行使用全局变量,后续遍历数组时也不会重新计算这两个变量的值,自然无法正确判断每个元素的情况。
把判断逻辑抽离的思路是可行的,但不能用全局变量存储计算结果,得把逻辑封装成可复用的动态判断单元,比如方法或Lambda。
解决方法
方案1:封装成独立方法
将整除判断逻辑写成方法,遍历元素时传入当前的numb,就能动态计算每个元素的条件:
def divisible_by_2?(numb) numb % 2 == 0 end def divisible_by_3?(numb) numb % 3 == 0 end numb_array = (0..100) numb_array.each do |numb| if divisible_by_2?(numb) && divisible_by_3?(numb) puts "fizzbuzz" elsif divisible_by_2?(numb) puts "buzz" elsif divisible_by_3?(numb) puts "fizz" else puts "none" end end
额外说明:你原本使用select方法,但select的作用是筛选元素并返回新数组,你的代码仅做打印操作,并未利用select的返回值,用each更贴合语义。
方案2:用Lambda封装逻辑
如果不想单独定义方法,也可以用Lambda存储判断逻辑,同样能实现动态计算:
div_by_2 = ->(numb) { numb % 2 == 0 } div_by_3 = ->(numb) { numb % 3 == 0 } numb_array = (0..100) numb_array.each do |numb| if div_by_2.call(numb) && div_by_3.call(numb) puts "fizzbuzz" elsif div_by_2.call(numb) puts "buzz" elsif div_by_3.call(numb) puts "fizz" else puts "none" end end
关键提示
若想复用判断逻辑,不能直接存储计算后的布尔值,而是要存储计算逻辑本身(方法、Lambda这类可调用对象),这样每次传入不同的numb时,才能得到对应的判断结果。
内容的提问来源于stack exchange,提问作者M C
相关产品推荐
相关产品推荐

