我没有从Integer中的以下猴子修补方法得到正确的结果:
def harm
1 + (2..self).inject{|sum, x| sum + 1/x.to_r}
end
2.harm #=> 3
它应该返回3/2而不是,我的错误在哪里?
答案 0 :(得分:4)
这里有两个问题:
当你在一个封闭的范围内迭代时,例如2..2
,实际上什么也没发生:
(0..0).inject(){|s, x| s+= 99 }
# => 0
这就是为什么你得到3
,因为1 + 2
是3
。
如果你没有将参数传递给inject
,它会使用你传递给迭代器的第一个值作为起始备忘录,即2
:
(2..2).inject(){|s, x| s+= 99 }
#=> 2
输入0可以获得实际的迭代:
(2..2).inject(0){|s, x| s+= 99 }
#=> 99
请在您的方法中尝试使用此方法:
1 + (2..self).inject(0){|sum, x| sum + 1/x.to_r}
独立:
1 + (2..2).inject(0){|sum, x| sum + 1/x.to_r}
#=> 3/2
答案 1 :(得分:2)
以下是提示(您需要将初始值传递给inject
方法):
def harm
1 + (2..2).inject(0){|sum, x| sum + 1/x.to_r}
end
harm # => (3/2)
如果指定一个块,那么对于枚举中的每个元素,块将传递一个累加器值(memo)和元素。如果指定了符号,则集合中的每个元素都将传递给命名的备忘录方法。在任何一种情况下,结果都将成为备忘录的新值。在迭代结束时,memo的最终值是方法的返回值。
如果没有明确指定备忘录的初始值,那么集合的第一个元素将用作备忘录的初始值。
答案 2 :(得分:1)
在我决定花费你的问题的1分钟内,我无法意识到你的代码有什么问题。但是我能够编写这种类似于你想做的事情的方法:
class Integer
def harm
return 0 if self == 0
return -(-self).harm if self < 0
( 1 .. self ).map { |n| Rational 1, n }.reduce :+
end
end
0.harm #=> 0
2.harm #=> 3/2
7.harm #=> 363/140
-2.harm #=> (-3/2)
但请注意,对于大量数据,这种高度可读的代码效率低下,因为它在执行求和之前在内存中准备数组。