В чем разница между Ruby + и concat для массивов? - PullRequest
2 голосов
/ 14 июня 2019

Я пытался собрать массивы с цифрами в один массив. Если я пытаюсь использовать +, он возвращает массив 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 ]

5 голосов
/ 14 июня 2019

В отличие от 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 голос
/ 14 июня 2019

Давайте создадим два массива:

a = [1, 2]
b = [3, 4]

Как и все объекты, эти массивы имеют уникальные идентификаторы объектов:

a.object_id  #=> 48242540181360 
b.object_id  #=> 48242540299680 

Теперь давайте сложим их вместе:

c = a + b    #=> [1, 2, 3, 4] 

Это создает новый объект (содержащий переменную c):

c.object_id  #=> 48242540315060 

и оставляет (объекты, удерживаемые) a и b (и их идентификаторы объектов) без изменений:

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:

a            #=> [1, 2, 3, 4, 3, 4] 
a.object_id  #=> 48242541482040  

Наконец, мы можем заменить значение a на c, не затрагивая идентификатор объекта a:

a.replace(c) #=> [1, 2, 3, 4]
a            #=> [1, 2, 3, 4] 
a.object_id  #=> 48242541482040

См. Array # + , Array # concat и Array # replace .

...