Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么是ruby';s&x27;你的计算不对吗?_Ruby_Enumerators - Fatal编程技术网

为什么是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)