# Multimimensional arrays - i am not getting it

**URL:** <https://www.ruby-forum.com/t/multimimensional-arrays-i-am-not-getting-it/104516>\
**Category:** Ruby\
**Created:** [May 18, 2007, 10:42pm UTC](https://www.ruby-forum.com/t/multimimensional-arrays-i-am-not-getting-it/104516 "2007-05-18T22:42:14Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![spacechurro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d2c977/32.png) [@spacechurro](https://www.ruby-forum.com/u/spacechurro)\
**Post date:** [May 18, 2007, 10:42pm UTC](https://www.ruby-forum.com/t/multimimensional-arrays-i-am-not-getting-it/104516/1 "2007-05-18T22:42:14Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![spacechurro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d2c977/32.png) [@spacechurro](https://www.ruby-forum.com/u/spacechurro)\
**Post date:** [May 18, 2007, 10:55pm UTC](https://www.ruby-forum.com/t/multimimensional-arrays-i-am-not-getting-it/104516/2 "2007-05-18T22:55:58Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![spacechurro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d2c977/32.png) [@spacechurro](https://www.ruby-forum.com/u/spacechurro)\
**Post date:** [May 18, 2007, 11:00pm UTC](https://www.ruby-forum.com/t/multimimensional-arrays-i-am-not-getting-it/104516/3 "2007-05-18T23:00:04Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![spacechurro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d2c977/32.png) [@spacechurro](https://www.ruby-forum.com/u/spacechurro)\
**Post date:** [May 18, 2007, 11:30pm UTC](https://www.ruby-forum.com/t/multimimensional-arrays-i-am-not-getting-it/104516/4 "2007-05-18T23:30:27Z")

</div>

In message [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid), Sergio  
Ruiz writes:

> > > a = Array.new(3,[])  
> > > =\> [[], [], []]  
> > > a[2] \<\< “check”  
> > > =\> [“check”]  
> > > a  
> > > =\> [[“check”], [“check”], [“check”]]
> 
> this is totally not what i am expecting…

I don’t see why. You initialized an array with three copies of the SAME  
empty  
array.

-s

---

<div class="post-metadata">

**Author:** ![spacechurro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d2c977/32.png) [@spacechurro](https://www.ruby-forum.com/u/spacechurro)\
**Post date:** [May 18, 2007, 11:32pm UTC](https://www.ruby-forum.com/t/multimimensional-arrays-i-am-not-getting-it/104516/5 "2007-05-18T23:32:27Z")

</div>

In message [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid), Mike  
Fletcher writes:

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

You could just do {[]} for the block. It DWYM.

-s

---

<div class="post-metadata">

**Author:** ![spacechurro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d2c977/32.png) [@spacechurro](https://www.ruby-forum.com/u/spacechurro)\
**Post date:** [May 20, 2007, 1:19pm UTC](https://www.ruby-forum.com/t/multimimensional-arrays-i-am-not-getting-it/104516/6 "2007-05-20T13:19:34Z")

</div>

Heh I remember when I made this mistake 🙂

---

<div class="post-metadata">

**Author:** ![spacechurro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d2c977/32.png) [@spacechurro](https://www.ruby-forum.com/u/spacechurro)\
**Post date:** [May 18, 2007, 11:00pm UTC](https://www.ruby-forum.com/t/multimimensional-arrays-i-am-not-getting-it/104516/7 "2007-05-18T23:00:23Z")

</div>

Alle venerdÃ¬ 18 maggio 2007, Sergio R. ha scritto:

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