我一直试图将具有数字的数组收集到一个数组中。如果我尝试使用+,它将返回emty数组作为输出。使用concat返回期望的数字数组。它是如何工作的,以及这些Ruby方法之间的主要区别是什么?
0.step.with_object([]) do |index, output|
output + [index]
break output if index == 100
do # returns empty array
0.step.with_object([]) do |index, output|
output.concat [index]
break output if index == 100
end # returns an array contains digits from 0 to 100
答案 0 :(得分:5)
与Enumerable#reduce
不同,Enumerable#each_with_object
通过归约过程传递相同的对象。
Array#+
创建一个新实例,使原始对象保持未路由状态。
Array#concat
变异原始对象。
对于reduce
,结果将相同:
0.step.reduce([]) do |acc, index|
break acc if index > 100
acc + [index]
end
答案 1 :(得分:1)
让我们创建两个数组:
a = [1, 2]
b = [3, 4]
与所有对象一样,这些数组具有唯一的对象ID:
a.object_id #=> 48242540181360
b.object_id #=> 48242540299680
现在让我们将它们添加在一起:
c = a + b #=> [1, 2, 3, 4]
这将创建一个新对象(由变量c
持有):
c.object_id #=> 48242540315060
并保留a
和b
(及其对象ID)(由它们保存的对象):
a #=> [1, 2]
b #=> [3, 4]
现在,让我们写:
a += b #=> [1, 2, 3, 4]
将Ruby更改为:
a = a + b
在编译代码时。我们获得:
a #=> [1, 2, 3, 4]
a.object_id #=> 48242541482040
变量a
现在包含一个新对象,该对象等于先前的值a
加b
。
现在让我们将b
与a
(的新值)连接起来:
a.concat(b) #=> [1, 2, 3, 4, 3, 4]
这会更改(变异)a
,但当然不会更改a
的对象ID:
a #=> [1, 2, 3, 4, 3, 4]
a.object_id #=> 48242541482040
最后,我们可以将a
的值替换为c
,而不会影响a
的对象ID:
a.replace(c) #=> [1, 2, 3, 4]
a #=> [1, 2, 3, 4]
a.object_id #=> 48242541482040