Ruby 使用\u对象分析.inject与每个\u

Ruby 使用\u对象分析.inject与每个\u,ruby,Ruby,我知道每一个带有_object的都不适用于像integer这样的不可变对象 例如(1..3)。每个_与_对象(0){| i,sum | sum+=i}#=>0 我们可以用inject来解决这个问题,总和将是6。太好了 让我们再举一个例子 ("a".."c").each_with_object("") {|i,str| str += i} # => "" 这也行不通,因为当我们执行str+=i时,我们会创建一个新对象 相反,我们需要这样做 ("a".."c").each_with_obje

我知道
每一个带有_object的
都不适用于像
integer
这样的不可变对象

例如
(1..3)。每个_与_对象(0){| i,sum | sum+=i}#=>0

我们可以用inject来解决这个问题,总和将是
6
。太好了

让我们再举一个例子

("a".."c").each_with_object("") {|i,str| str += i} # => ""
这也行不通,因为当我们执行
str+=i
时,我们会创建一个新对象

相反,我们需要这样做

("a".."c").each_with_object("") {|i,str| str << i} # => "abc"
为什么第一次打印的abc是反向的?为什么第二个是错误

我知道我们应该使用
.each_with_object
来表示可变对象,使用
inject
来表示不可变对象(比如
Integer
),但是我可以使用吗
.inject
用于可变对象,就像
一样。每个带有对象的\u
?有人能解释这些结果吗

为什么第一次打印abc是反向的

参数是反向的。请参阅

打印
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
为什么第二个是错误

无论如何,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]
$ruby-e'put(“a”.“c”).inject(“”{i,str | str ERROR”
中国篮球协会
$ruby-v
ruby 2.2.4p230(2015-12-16修订版53155)[x86_64-darwin15]

因此
.inject
可以在所有情况下用对象替换
每个\u
?是否存在一个案例
。每个\u with \u object
都可以用于inject不能使用的情况?@bill
每个\u with \u object
不关心块的返回值,这很好,不必确保始终返回正确的对象。例如
(“a”。“c”)。每个带有{}对象({})的{e,obj}obj[e]=e.next}
第一次查看的返回值实际上是“b”,这与inject
(“a”。“c”)。inject({})对象({obj,e{obj[e]=e.next}
。这必须更改为
(“a”。“c”)。inject({})对象({e,obj}=e.next;{
@engineersmnky,你能解释一下这两个例子中都发生了什么吗,我不太明白,所以inject只返回块值,而每个带有对象的_将返回obj。顺便说一下,
(“a”。“c”).inject({})e,obj{obj[e]=e.next;obj}
,不起作用irb@bill是的,输入错误应该是
(“a”。“c”)。注入({}){obj,e | obj[e]=e.next;obj}
我在复制
每个带有对象的
实现时,意外地忘记了反转管道参数。您也可以编写
(“a”。“c”)。每个带有对象的{s,str | str str.replace(str+s)}=>“abc”
。注意我使用了
s
(对于“字符串”,或者我可能使用了
c
“字符”)由于块变量
i
通常表示一个索引。我不知道
每个带有\u对象的\u
不能替换为
inject
,但不能提供该断言的证明。
$ 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]