Redouane Red
Redouane Red

Reputation: 539

Cloning an array with its content

I want to make a copy of an array, to modify the copy in-place, without affecting the original one. This code fails

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 should be different than the object. Why does it act like if it were just a reference?

Upvotes: 32

Views: 46335

Answers (6)

cesartalves
cesartalves

Reputation: 1585

You can just map the elements of the array. I believe this is the cleanest solution as of today.

array.map(&:itself)

Upvotes: 4

Zachary White
Zachary White

Reputation: 133

You can use #dup which creates a shallow copy of the object, meaning "the instance variables of object are copied, but not the objects they reference." For instance:

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.

Upvotes: 10

wjordan
wjordan

Reputation: 20390

Instead of calling clone on the array itself, you can call it on each of the array's elements using map:

b = a.map(&:clone)

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

Upvotes: 28

Maya Novarini
Maya Novarini

Reputation: 349

Try this:

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 content are the same.

Upvotes: 7

Anutosh
Anutosh

Reputation: 29

Not sure , if this is answered anywhere else. Tried searching but no success.

Try this

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 this helps.

Upvotes: -1

jazzytomato
jazzytomato

Reputation: 7214

You need to do a deep copy of your array.

Here is the way to do it

Marshal.load(Marshal.dump(a))

This is because you are cloning the array but not the elements inside. So the array object is different but the elements it contains are the same instances. You could, for example, also do a.each{|e| b << e.dup} for your case

Upvotes: 26

Related Questions