3

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?

2
  • 2
    Actually, both do not work as transpose. The first one looks like it does because you are using a special example that has the same number of rows and columns. Commented Oct 12, 2015 at 4:16
  • << this will work like appending means new[0] << 1 then new[0] << 3 then new [0] << 5 .... so new[0] = [1, 3, 5, 2, 4, 6, 7, 9, 8]... same of Commented Oct 12, 2015 at 4:17

1 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.