ruby – .inject vs .each_with_object的分析

我知道each_with_object对整数这样的不可变对象不起作用.

例如(1..3).each_with_object(0){| i,sum | sum = i}#=> 0

我们可以通过注入解决这个问题,总和将是6.太棒了!

让我们再看一个例子

("a".."c").each_with_object("") {|i,str| str += i} # => ""

这不起作用,因为当我们做str = i时,我们创建一个新对象

相反,我们需要这样做

("a".."c").each_with_object("") {|i,str| str << i} # => "abc"

为什么当我用以下两种方式注射时,我会得到奇怪的结果

("a".."c").inject("") {|i,str| str += i} # => cba

("a".."c").inject("") {|i,str| str << i} # => ERROR

为什么第一次打印abc反向?为什么第二个错误?

我知道我们应该使用.each_with_object用于可变对象,并注入不可变(如Integer),但是我可以使用
.inject为可变对象以及.each_with_object?谁能解释这些结果?

最佳答案

Why is the first printing abc in reverse?

争论是倒退的.见Enumerable#inject.

打印i和str显示问题.

$ruby -e '("a".."c").inject("") {|i,str| puts "i   = #{i}"; puts "str = #{str}"; ret = str += i; puts "ret = #{ret}\n\n"; ret }'
i   = 
str = a
ret = a

i   = a
str = b
ret = ba

i   = ba
str = c
ret = cba

i是最后一次通过该块返回的累计金额. str是下一个值.您将之前的累计值添加到下一个累计值.你有倒退的论点.第一个是总和,第二个是下一个元素.

当它被纠正后,它可以正常工作.

$ruby -e 'puts ("a".."c").inject("") {|sum,i| sum += i}'
abc

此外,它是使用的块的返回值.改变str没有效果,它只会让事情进一步混乱.

$ruby -e 'puts ("a".."c").inject("") {|sum,i| sum + i}'
abc

And why is the second an error?

不是,不是在Ruby 2.0.0和2.2.4中.但它有同样的向后args问题.

$ruby -e 'puts ("a".."c").inject("") {|i,str| str << i} # => ERROR'
cba

$ruby -v
ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-darwin15]
点赞