2

我一直在尝试将带有数字的数组收集到一个数组中。如果我尝试使用 + 它会返回 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
4

2 回答 2

5

与 不同Enumerable#reduceEnumerable#each_with_object通过归约过程传递相同的对象。

Array#+创建一个新实例,使原始对象保持原样。改变原始对象。
Array#concat

结果将reduce是相同的:

0.step.reduce([]) do |acc, index|
  break acc if index > 100
  acc + [index]
end
于 2019-06-14T06:57:06.843 回答
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 

并保持(持有的对象)ab(及其对象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现在包含一个新对象,该对象等于aplus的先前值b

现在让我们b与 (the new value of)连接a

a.concat(b)  #=> [1, 2, 3, 4, 3, 4]  

这会改变(mutatesa,但当然不会改变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

请参阅Array#+Array#concatArray#replace

于 2019-06-14T08:06:35.857 回答