ctilley79 ctilley79 - 7 months ago 15
Ruby Question

Ruby 2.3: Cannot duplicate an array. Original array modified

I'm performing operations on arrays and I'm running into some issues. I duplicated

array_1
assigning it to
array_2
. When I did operations on array_2, the
uniq
method modifies the original array.

array_3
is what I intended accomplish, but I don't understand why the operations to get there modified
array_1


I need an explanation why this behavior occurs, and what I can do to prevent this from happening.

array_1 = [["Ed","2",],["Ann","2"],["Sue","2"],["Ed","3",],["Ann","3"],["Sue","3"]]

array_2 = array_1.dup
array_2 = array_2.uniq(&:first)

array_3=[]
array_2.each do |a2|
a2.pop
array_3.push(a2)
end

puts array_3
=> [["Ed"], ["Ann"], ["Sue"]]

puts array_1
=> [["Ed"], ["Ann"], ["Sue"], ["Ed", "3"], ["Ann", "3"], ["Sue", "3"]]

Answer

The problem is this line:

array_2 = array_1.dup

From the docs:

dup

Produces a shallow copy of obj—the instance variables of obj are copied, but not the objects they reference.

So array_2 consists of pointers to the same subarrays that are in array_1. Now pop mutates its array. So when you pop a subarray in array_2, it affects the same subarray in array_1.

You'll get the result you seem to expect if you say

array_2 = array_1.map(&:dup)

Personally, though, I would change

a2.pop
array_3.push(a2)

to

array_3.push(a2[0])

I don't see what you gain by mutating the subarrays (though perhaps something is going on that you have not told us).

Comments