[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

multimimensional arrays - i am not getting it..

Sergio Ruiz

5/18/2007 8:42:00 PM

let me just give a blip of what i am getting...

>> a = Array.new(3,[])
=> [[], [], []]
>> a[2] << "check"
=> ["check"]
>> a
=> [["check"], ["check"], ["check"]]

this is totally not what i am expecting..

what i am expecting is:

[[],[],[["check"]]]

as in..

the 2 element should have the "check" string dropped into the next
available position..

how would i go about setting that (or any other) element only?

thanks!

--
Posted via http://www.ruby-....

4 Answers

Mike Fletcher

5/18/2007 8:56:00 PM

0

Sergio Ruiz wrote:
> let me just give a blip of what i am getting...
>
>>> a = Array.new(3,[])
> => [[], [], []]

You've made an array containing three copies of a reference to the same
array instance.

irb(main):001:0> a = Array.new( 3, [] )
=> [[], [], []]
irb(main):002:0> a.each_with_index { |x,i| puts "#{i}: #{x.object_id}" }
0: 8484280
1: 8484280
2: 8484280

I believe you'd want:

a = Array.new( 3 ) { |idx| Array.new() }

That will call the block once for each element, and that block will
create a new (different) array instance each time it's called.


irb(main):001:0> a = Array.new( 3 ) { |idx| Array.new }
=> [[], [], []]
irb(main):002:0> a[2] << "foo"
=> ["foo"]
irb(main):003:0> a
=> [[], [], ["foo"]]
irb(main):004:0> a.each_with_index { |x,i| puts "#{i}: #{x.object_id}" }
0: 2741440
1: 2741430
2: 2741420

--
Posted via http://www.ruby-....

Stefano Crocco

5/18/2007 9:00:00 PM

0

Alle venerdì 18 maggio 2007, Sergio Ruiz ha scritto:
> let me just give a blip of what i am getting...
>
> >> a = Array.new(3,[])
>
> => [[], [], []]
>
> >> a[2] << "check"
>
> => ["check"]
>
> >> a
>
> => [["check"], ["check"], ["check"]]
>
> this is totally not what i am expecting..
>
> what i am expecting is:
>
> [[],[],[["check"]]]
>
> as in..
>
> the 2 element should have the "check" string dropped into the next
> available position..
>
> how would i go about setting that (or any other) element only?
>
> thanks!

Look at the documentation for Array.new (ri Array.new). Array.new(n, obj)
creates an array with n entries, all containing the same object, obj. You can
see this comparing the entries' object_id, or using equal?: a[0].equal?(a[1])
=> true. Since all entries contain the same object, when you modify it, the
change shows everywhere in the array.

To fill the array with *different* empty arrays, you need to use the form of
Array.new which takes a block:

Array.new(3){[]}

In this form, the block is called for each index, with the index as argument
(you can omit it here because you don't need it). The result of the block is
stored in the corresponding entry. The point is that each time the block is
called, a *new* empty array is created and stored in the returned array. This
time, a[0].equal?(a[1]) gives false.

I hope this helps

Stefano

Sergio Ruiz

5/18/2007 9:00:00 PM

0


> You've made an array containing three copies of a reference to the same
> array instance.


got it!

dangit..

this tripped me up all day..

thanks!

--
Posted via http://www.ruby-....

Dan Stevens (IAmAI)

5/20/2007 11:19:00 AM

0

Heh I remember when I made this mistake :)

On 18/05/07, Sergio Ruiz <sergio@village-buzz.com> wrote:
>
> > You've made an array containing three copies of a reference to the same
> > array instance.
>
>
> got it!
>
> dangit..
>
> this tripped me up all day..
>
> thanks!
>
> --
> Posted via http://www.ruby-....
>
>