数组的Ruby +和concat有什么区别?

时间:2019-06-14 06:53:48

标签: arrays ruby concat step

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

2 个答案:

答案 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 

并保留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现在包含一个新对象,该对象等于先前的值ab

现在让我们将ba(的新值)连接起来:

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

请参见Array#+Array#concatArray#replace