[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How to duplicate elements in array?

Chris Chris

7/3/2008 8:08:00 PM

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
--
Posted via http://www.ruby-....

6 Answers

Phlip

7/3/2008 8:21:00 PM

0

Chris Chris wrote:

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

> a2 = a + a

> a2[0][1] = "test"

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

a is an object, not a value. a + a sez "make an array containing two links to
this object". Changing one object changes the other.

You need a2 = a.dup + a.clone

I forget the difference between .dup and .clone, though... (-:

--
Phlip

Marc Heiler

7/3/2008 8:25:00 PM

0

> a2 = a.dup + a.clone

That gives the same result as his example.

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

(Hopefully that link works)
--
Posted via http://www.ruby-....

Leslie Viljoen

7/3/2008 8:40:00 PM

0

On 7/3/08, Chris Chris <kylejc@gmx.net> wrote:
> 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

Phlip

7/3/2008 8:44:00 PM

0

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

Or try this savage hack:

a2 = eval(a.inspect) + a

(-:

Chris Chris

7/3/2008 8:46:00 PM

0

>> 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
--
Posted via http://www.ruby-....

David A. Black

7/4/2008 1:18:00 AM

0

Hi --

On Fri, 4 Jul 2008, phlip wrote:

>>> 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?

The most common idiom for deep copying is:

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


David

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails July 21-24 Edison, NJ
Advancing With Rails August 18-21 Edison, NJ
See http://www.r... for details and updates!