I'm trying to write my own transpose method. I'm wondering how the different forms of concatenation are affecting my code.
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]]
Why do they not work in an identical fashion?
With
new = Array.new(multi.length, [])
# => [[], [], []]
the elements in new refer to the same Array objects. Check their id:
new.map {|e| e.object_id}
# => [1625920, 1625920, 1625920]
The first code snippet gives you the expected result because new[y] += [x] assigns to new[y] a new Array object, so each element in new now doesn't refer to the same object:
new.map {|e| e.object_id}
# => [22798480, 22798440, 22798400]
With the second code snippet, each element in new still refers to the original Array object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With