Cloning an array with its contents

I want to make a copy of an array so that I can change the copy in place without affecting the original one. This code doesn't work

a = [
  '462664',
  '669722',
  '297288',
  '796928',
  '584497',
  '357431'
]
b = a.clone
b.object_id == a.object_id # => false
a[1][2] = 'X'
a[1] #66X722
b[1] #66X722

      

The copy must be different from the object. Why does this work if it's just a link?

+9


source to share


5 answers


You need to make a deep copy of your array.

Here's how to do it



Marshal.load(Marshal.dump(a))

      

This is because you are cloning the array, but not internally. So the array object is different, but the elements it contains are the same. For example, you can do a.each{|e| b << e.dup}

for your case

+11


source


Instead of calling it clone

on the array itself, you can call it on each element of the array using map

:

b = a.map(&:clone)

      



This works in the example in the question, because you get a new instance for each element in the array.

+7


source


Try the following:

b = [] #create a new array 
b.replace(a) #replace the content of array b with the content from array a

      

At this point, these two arrays are references to different objects, and the content is the same.

+6


source


You can use #dup, which creates a shallow copy of an object, which means "the object's instance variables are copied, but not the objects they refer to." For example:

a = [1, 2, 3]

b = a.dup

b # => [1, 2, 3]

      

Source: https://ruby-doc.org/core-2.5.3/Object.html#method-i-dup

Edit: Listen to Paul below me. I misunderstood the question.

+2


source


Not sure if this answers anywhere else. Tried searching but didn't have time.

try it

current_array =["a", "b","c","d"]
new_array = current_array[0 .. current_array.length]
new_array[0] ="cool"

output of new_array
 "cool","b","c","d"

      

Hope it helps.

-1


source







All Articles