multimimensional arrays - i am not getting it..

S

Sergio Ruiz

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!
 
M

Mike Fletcher

Sergio said:
let me just give a blip of what i am getting...
=> [[], [], []]

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
 
S

Stefano Crocco

Alle venerd=C3=AC 18 maggio 2007, Sergio Ruiz ha scritto:
let me just give a blip of what i am getting...
a =3D Array.new(3,[])

=3D> [[], [], []]

=3D> ["check"]

=3D> [["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)=20
creates an array with n entries, all containing the same object, obj. You c=
an=20
see this comparing the entries' object_id, or using equal?: a[0].equal?(a[1=
])=20
=3D> true. Since all entries contain the same object, when you modify it, t=
he=20
change shows everywhere in the array.

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

Array.new(3){[]}

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

I hope this helps

Stefano
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top