How to duplicate elements in array?

C

Chris Chris

Hi,

something I couldn't quite figure out (sorry for posting so soon after
my last question)...

a = [["ABC", "30", "1"]]

I want to duplicate/copy the element. This is what I'm trying to get:

a2 = [["ABC", "30", "1"], ["ABC", "30", "1"]]

What I did was simply

a2 = a + a

=> [["ABC", "30", "1"], ["ABC", "30", "1"]]

That works.

I then tried changing a single element.

a2[0][1] = "test"

puts a2.inspect
=> [["ABC", "test", "1"], ["ABC", "test", "1"]]

Of course, I just intended to change the first value, not both of them.


Can anybody explain please what I can do about this?

Thank you!

Chris
 
L

Leslie Viljoen

Hi,

something I couldn't quite figure out (sorry for posting so soon after
my last question)...

a = [["ABC", "30", "1"]]

I want to duplicate/copy the element. This is what I'm trying to get:

a2 = [["ABC", "30", "1"], ["ABC", "30", "1"]]

What I did was simply

a2 = a + a

=> [["ABC", "30", "1"], ["ABC", "30", "1"]]

That works.

I then tried changing a single element.

a2[0][1] = "test"

puts a2.inspect
=> [["ABC", "test", "1"], ["ABC", "test", "1"]]

Of course, I just intended to change the first value, not both of them.


Can anybody explain please what I can do about this?

You need to use .dup:
a = ["ABC", "30", "1"] => ["ABC", "30", "1"]
b = a.dup => ["ABC", "30", "1"]
b[0] = "DEF" => "DEF"
a => ["ABC", "30", "1"]
b
=> ["DEF", "30", "1"]

If you just assign an object, you get another reference to the same
object. DUP will give you a copy, although not a deep copy. That means
that if

a = [["ABC", "30", "1"]], a.dup will not give you a copy of the
element within the array - it will give you a copy of the array with
the inner element being a reference again:
a = [["ABC", "30", "1"]] => [["ABC", "30", "1"]]
b = a.dup => [["ABC", "30", "1"]]
b[0][0] = "DEF" => "DEF"
a => [["DEF", "30", "1"]]
b
=> [["DEF", "30", "1"]]

The easy way to do deep copies is to use Marshal.

Les
 
P

phlip

a2 = a.dup + a.clone
That gives the same result as his example.

Indeed - it only cloned the top level of a, which is an array. The rest remained
a linked-too object.

How to deep clone?
Dunno if you can understand german.. at least the examples are in
english, maybe you understand what is going on despite being unable to
understand anything :)

http://forum.ruby-portal.de/viewtopic.php?t=1214

Or try this savage hack:

a2 = eval(a.inspect) + a

(-:
 
C

Chris Chris

a = [["ABC", "30", "1"]]
a2 = a + a
a2[0][1] = "test"
=> [["ABC", "test", "1"], ["ABC", "test", "1"]]

Thanks guys. Yeah, I speak German :)... Going through that discussion
solved it for me after tweaking it a little bit...

Changed
a = [["ABC", "30", "1"]] TO a = ["ABC", "30", "1"]

a2 = [a.dup, a.dup]

a2[0][1] = "test"

=> [["ABC", "test", "1"], ["ABC", "30", "1"]]

Chris
 
D

David A. Black

Hi --

Indeed - it only cloned the top level of a, which is an array. The rest
remained a linked-too object.

How to deep clone?

The most common idiom for deep copying is:

copy = Marshal.load(Marshal.dump(original))


David
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top