做的第一个项目欧拉问题:3和5倍数总结1和1000之间,我想出了这个(很简单)红宝石注入有条件的块?
sum = 0
1.upto(999) { |i| sum += i if 0 == i%3 || 0 == i%5 }
sum
,但我认为这会工作,但它没有,可以有人告诉我我做错了什么,或者为什么它不起作用?
1.upto(999).inject(0) { |sum, i| sum + i if 0 == i%3 || 0 == i%5 }
谢谢!
做的第一个项目欧拉问题:3和5倍数总结1和1000之间,我想出了这个(很简单)红宝石注入有条件的块?
sum = 0
1.upto(999) { |i| sum += i if 0 == i%3 || 0 == i%5 }
sum
,但我认为这会工作,但它没有,可以有人告诉我我做错了什么,或者为什么它不起作用?
1.upto(999).inject(0) { |sum, i| sum + i if 0 == i%3 || 0 == i%5 }
谢谢!
inject
将块的结果作为第一个参数传递给下一次迭代。当您的if
声明为false时,您的区块将返回nil
,然后以sum
作为传回。
为了得到正确的答案,该块应该返回电流和当它是假的:
1.upto(999).inject(0) { |sum, i| (0 == i%3 || 0 == i%5) ? sum + i : sum }
1.upto(999).inject(0) { |sum, i| sum += i if 0 == i%3 || 0 == i%5; sum }
也将工作(注意+=
)。
补充回答:如果您即将解决欧拉问题,您应该开始构建自己的可重用代码的扩展。在这种情况下,第一扩展是Enumerable#sum
:
module Enumerable
def sum
inject(0, :+)
end
end
现在,您可以编写分隔summatory的条件的方案(你可以大声读出来,它是有道理的,这是典型的功能/声明的风格):
1.upto(999).select { |x| x % 3 == 0 || x % 5 == 0 }.sum
你甚至可以将其推一步,创造Fixnum#divisible_by?
所以你可以写:
1.upto(999).select { |x| x.divisible_by?(3) || x.divisible_by?(5) }.sum
更多:这里是不是问题,但后来严格的实现(使用数组的)将需要太多的内存。与laziness然后尝试:
require 'lazy'
1.upto(999).lazy.select { |x| x % 3 == 0 || x % 5 == 0 }.sum
这是很棒的信息。我将按照其中的几个问题关注它,并且看到建议的实用性。谢谢! – Tonys
或者,使用&
PROC其中涉及自我。
(1..999).select{|x| x%3==0||x%5==0}.inject &:+
(1..999).to_a.keep_if{|d| d%3 == 0 || d%5 == 0}.reduce(:+)
为完整性。
感谢您的alt答案。这更接近我的初始设置,所以我可能会这样做(更易读),我接受了第一个答案,因为错误的解释 - '啊哈!'给我帮助的时刻 – Tonys