0

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"]]
1

1 Answer 1

3

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).

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

3 Comments

Please don't advise people to do Marshal.load(Marshal.dump(array_1)), or at least mention that it's almost always the wrong solution. In this case array_1.map(&:dup) would suffice.
this is part of a larger program. I need to keep the sub arrays intact. I'm using these examples to learn the inner workings of ruby when a problem stumps me
That is why I said that perhaps something is going on that you have not told us.

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.