为什么是ruby';s&x27;你的计算不对吗?
我无法从以下整数中的猴子修补方法中获得正确的结果:为什么是ruby';s&x27;你的计算不对吗?,ruby,enumerators,Ruby,Enumerators,我无法从以下整数中的猴子修补方法中获得正确的结果: def harm 1 + (2..self).inject{|sum, x| sum + 1/x.to_r} end 2.harm #=> 3 它应该返回3/2,我的错误在哪里?这里是提示(您需要将初始值传递给inject方法): 文件: 如果指定一个块,则为枚举中的每个元素传递一个累加器值(memo)和元素。如果改为指定符号,则集合中的每个元素都将传递给memo的命名方法。在任何一种情况下,结果都将成为memo的新值。迭代结束时
def harm
1 + (2..self).inject{|sum, x| sum + 1/x.to_r}
end
2.harm #=> 3
它应该返回3/2,我的错误在哪里?这里是提示(您需要将初始值传递给inject
方法):
文件:
如果指定一个块,则为枚举中的每个元素传递一个累加器值(memo)和元素。如果改为指定符号,则集合中的每个元素都将传递给memo的命名方法。在任何一种情况下,结果都将成为memo的新值。迭代结束时,memo的最终值是该方法的返回值
如果未明确指定备注的初始值,则集合的第一个元素将用作备注的初始值
这里有两个问题:
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分钟的时间讨论你的问题时,我无法意识到你的代码出了什么问题。但是我能够编写这个方法,它可以做一些类似于您想要做的事情:
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)
类整数
def伤害
如果self==0,则返回0
返回-(-self)。如果self<0,则会造成伤害
(1..self).映射{n|有理1,n}.约化:+
结束
结束
0.harm#=>0
2.harm#=>3/2
7.harm#=>363/140
-2.harm#=>(-3/2)
但是,请注意,对于较大的数字,这种高度可读的代码会变得效率低下,因为它会在执行求和之前在内存中准备数组。它完全按照您的要求执行。说它“总和不正确”有误导性。默认的初始值是什么?不需要传递初始值,如果不显式传递初始值,则初始值是数组中的第一项。@meagar在IRB中尝试相同的代码,初始参数为
0
,没有0
。。你可以看到差别。。文件中也解释了原因。。我也在这里链接并粘贴了…)@ArupRakshit我知道inject
是如何工作的。如果没有显式传递,则初始值是枚举中的第一项,这通常是正确的。您的第一句话是正确的,但是1+2+1/2。to\r
不是。如果是这样的话,结果将是7/2
。编辑它…当没有传递初始备忘录时,inject
的行为与我想象的不同in@Boris... 好久不见……)你好吗?@收到你的消息了,我太忙了,还没来得及回复:-)很高兴收到你的来信,很高兴看到你很活跃:-)@boris。。我很高兴终于得到了你的答复……:)
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)