2015-10-12 4 views
3

Я пытаюсь написать свой собственный метод транспонирования. Мне интересно, как различные формы конкатенации влияют на мой код.Разница между типами конкатенаций в ruby ​​

multi = [[1,3,5],[2,4,6],[7,9,8]] 
new = Array.new(multi.length, []) 
multi.each do |c| 
    c.each_with_index do |x,y| 
     new[y] += [x] 
    end 
end 
new #=> [[1, 3, 5], [2, 4, 6], [7, 9, 8]] 

multi = [[1,3,5],[2,4,6],[7,9,8]] 
new = Array.new(multi.length, []) 
multi.each do |c| 
    c.each_with_index do |x,y| 
     new[y] << x 
    end 
end 
new #=> [[1, 3, 5, 2, 4, 6, 7, 9, 8], [1, 3, 5, 2, 4, 6, 7, 9, 8], [1, 3, 5, 2, 4, 6, 7, 9, 8]] 

Почему они не работают в одинаковой манере?

+2

Фактически, оба не работают в качестве транспонирования. Первый выглядит так, потому что вы используете специальный пример, который имеет такое же количество строк и столбцов. – sawa

+0

<< это будет работать как добавочное средство new [0] << 1 then new [0] << 3 then new [0] << 5 .... так что 'new [0] = [1, 3, 5, 2, 4, 6, 7, 9, 8]. ... то же самое –

ответ

5

С

new = Array.new(multi.length, []) 
# => [[], [], []] 

элементов в new относятся к одинаковым Array объектов. Проверьте их ID:

new.map {|e| e.object_id} 
# => [1625920, 1625920, 1625920] 

Первый фрагмент кода дает ожидаемого результата, потому что new[y] += [x] присваивает new[y] новый объект Array, так что каждый элемент в new Теперь не ссылается на тот же объект:

new.map {|e| e.object_id} 
# => [22798480, 22798440, 22798400] 

С помощью второго фрагмента кода каждый элемент в new по-прежнему относится к исходному объекту Array.

Смежные вопросы