# multi-dimensional Arrays

Discussion in 'Ruby' started by Peter v. N., Oct 11, 2005.

1. ### Peter v. N.Guest

Hi all,

I'm a Ruby noob so please forgive me...

I know there exist "simple" ways (Google's thy friend)
to create md arrays with Ruby. But it's somehow cumbersome
and it would be nice if it could be done like "array = Array.new(3,3)"
-> I know too that this means not the same in Ruby...

What I like to know: what led to the decission to do it that way
and not like it is done in the C/C++ (Java) languages à la
"int[][] arr = new int[3][3]"?

Maybe because this approach is not strictly oo-oriented? But then,
switches and loops in Ruby are neither.

It's just the devil inside who likes to know about the philosophy
about the "why it is done like that" and I'm not bitching about
Ruby (by no means).

Thank you for a pointer or a short explanation.

Greetings,
Peter

Peter v. N., Oct 11, 2005

2. ### Brian SchröderGuest

On 11/10/05, Peter v. N. <> wrote:
> Hi all,
>
> I'm a Ruby noob so please forgive me...
>
> I know there exist "simple" ways (Google's thy friend)
> to create md arrays with Ruby. But it's somehow cumbersome
> and it would be nice if it could be done like "array =3D Array.new(3,3)"
> -> I know too that this means not the same in Ruby...
>
> What I like to know: what led to the decission to do it that way
> and not like it is done in the C/C++ (Java) languages =E0 la
> "int[][] arr =3D new int[3][3]"?

you do it the same as in c, you say that you want an array of arrays.
E.g.

arr =3D Array.new(3) { Array.new(3) }

which is the same as int[3][3] in c where iirc int[3][3] is not a
contiguous block of memory but pointers to arrays. If you want a

>
> Maybe because this approach is not strictly oo-oriented? But then,
> switches and loops in Ruby are neither.

In my opinion this has nothing to do with oo versus non oo. Switches
and loops are signs of imperative programming, which is oppsite to
functional and logical programming but orthogonal to object oriented
versus not object oriented.

>
> It's just the devil inside who likes to know about the philosophy
> about the "why it is done like that" and I'm not bitching about
> Ruby (by no means).
>
> Thank you for a pointer or a short explanation.
>
> Greetings,
> Peter
>
>

And beware that
Array.new(3, Array.new(3)) is not the same as Array.new(3) { Array.new(3) }

hope to help,

Brian

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

Brian Schröder, Oct 11, 2005

3. ### David A. BlackGuest

--8323328-294073984-1129034136=:19017
Content-Type: MULTIPART/MIXED; BOUNDARY="8323328-294073984-1129034136=:19017"

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

--8323328-294073984-1129034136=:19017
Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE

Hi --

On Tue, 11 Oct 2005, Peter v. N. wrote:

> Hi all,
>
> I'm a Ruby noob so please forgive me...

Welcome to Ruby!

> I know there exist "simple" ways (Google's thy friend)
> to create md arrays with Ruby. But it's somehow cumbersome
> and it would be nice if it could be done like "array =3D Array.new(3,3)" =

-> I=20
> know too that this means not the same in Ruby...
>
> What I like to know: what led to the decission to do it that way
> and not like it is done in the C/C++ (Java) languages =E0 la
> "int[][] arr =3D new int[3][3]"?
>
> Maybe because this approach is not strictly oo-oriented? But then,
> switches and loops in Ruby are neither.

OK... but finding a couple of things that aren't strictly OO doesn't
mean that Ruby should just give up and make everything non-OO
Each part of Ruby is carefully designed to contribute to the whole
system.

In the case of int[][] arr... Ruby variables are always untyped. If
you can do:

arr =3D []

you can also do:

arr =3D "I am not an array!"

The identifier 'arr' has no particular type. That's a big part of the
dynamics and dynamism of Ruby.

Also, you're assuming that [] means "array indexing". Actually, this:

x[]

is just syntactic sugar for this:

x.[] # call method "[]"

and you can define [] to do whatever you want:

obj =3D Object.new

# Define a "singleton" method [] for obj
def obj.[](x)
"Are you trying to access index #{x}??"
end

puts obj[3] # Are you trying to access index 3??

So there's no reason to think that the notation [][] would mean
"nested array".

There's a Matrix class, by the way, that might help you automate what
you need to do a little more.

David

--=20
David A. Black

--8323328-294073984-1129034136=:19017--
--8323328-294073984-1129034136=:19017--

David A. Black, Oct 11, 2005
4. ### Ara.T.HowardGuest

On Tue, 11 Oct 2005, Peter v. N. wrote:

> Hi all,
>
> I'm a Ruby noob so please forgive me...
>
> I know there exist "simple" ways (Google's thy friend) to create md arrays
> with Ruby. But it's somehow cumbersome and it would be nice if it could be
> done like "array = Array.new(3,3)" -> I know too that this means not the
> same in Ruby...
>
> What I like to know: what led to the decission to do it that way
> and not like it is done in the C/C++ (Java) languages à la
> "int[][] arr = new int[3][3]"?

this is precisely because these languages do __not__ have multi-dimensional
arrays and they muse be composed of uni-dimensional ones. ruby is the same.
the big difference is that there is no difference between compile time and
runtime in ruby so, if i could say

a = array[3]

in ruby, then

a = array[3][3]

would mean

a = (the_first_array = array[3])[ index = 3]

in otherwords you'd index the first array by the second value. another issue
is that, in ruby, a declaration is the same as a definition. so, in c, you
cannot write

printf ("%d\n", (int [42])[0]);

but in ruby you can write

printf "%d\n", [42][0]

because you can simoultaneously define and declare an object, and this have
object, including array, literals.

> Maybe because this approach is not strictly oo-oriented? But then, switches
> and loops in Ruby are neither.

i thinks it's more syntax/interpreter related.

> It's just the devil inside who likes to know about the philosophy about the
> "why it is done like that" and I'm not bitching about Ruby (by no means).

the best reason may be that's it's so easy to setup you're own md definer:

harp:~ > cat a.rb
require 'pp'

md = lambda{|*ds| Array::new(ds.shift||0).map{md[*ds] unless ds.empty?}}

pp md[]
pp md[1]
pp md[2]
pp md[2,3]
pp md[2,3,4]

harp:~ > ruby a.rb
[]
[nil]
[nil, nil]
[[nil, nil, nil], [nil, nil, nil]]
[[[nil, nil, nil, nil], [nil, nil, nil, nil], [nil, nil, nil, nil]],
[[nil, nil, nil, nil], [nil, nil, nil, nil], [nil, nil, nil, nil]]]

cheers.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| Your life dwells amoung the causes of death
| Like a lamp standing in a strong breeze. --Nagarjuna
===============================================================================

Ara.T.Howard, Oct 11, 2005
5. ### Martin DeMelloGuest

Peter v. N. <> wrote:
>
> I know there exist "simple" ways (Google's thy friend)
> to create md arrays with Ruby. But it's somehow cumbersome
> and it would be nice if it could be done like "array = Array.new(3,3)"
> -> I know too that this means not the same in Ruby...
>
> What I like to know: what led to the decission to do it that way
> and not like it is done in the C/C++ (Java) languages à la
> "int[][] arr = new int[3][3]"?

There are several different kinds of multidimensional arrays. One is
true rectangular arrays (efficient memory allocation, bounds checked in
every dimension) - I think FISh supports those[1], and probably Matlab
as well.

Then there's C's rectangular arrays with weak (no!) bounds checking -
the array is allocated as a contiguous block, and multidimensional
indexes are converted into (computed) single dimensional offsets into
the block.

And finally, Ruby uses the lists-of-lists approach, in which you have
only one-dimensional arrays, but every cell of those arrays can be an
array itself (and so on recursively). Not as efficient as the
rectangular approach, but it allows for irregularly shaped arrays.

martin

[1] http://www-staff.it.uts.edu.au/~cbj/FISh/Announcement/

Martin DeMello, Oct 11, 2005
6. ### Ara.T.HowardGuest

On Wed, 12 Oct 2005, Martin DeMello wrote:

> Peter v. N. <> wrote:
>>
>> I know there exist "simple" ways (Google's thy friend)
>> to create md arrays with Ruby. But it's somehow cumbersome
>> and it would be nice if it could be done like "array = Array.new(3,3)"
>> -> I know too that this means not the same in Ruby...
>>
>> What I like to know: what led to the decission to do it that way
>> and not like it is done in the C/C++ (Java) languages à la
>> "int[][] arr = new int[3][3]"?

>
> There are several different kinds of multidimensional arrays. One is
> true rectangular arrays (efficient memory allocation, bounds checked in
> every dimension) - I think FISh supports those[1], and probably Matlab
> as well.
>
> Then there's C's rectangular arrays with weak (no!) bounds checking -
> the array is allocated as a contiguous block, and multidimensional
> indexes are converted into (computed) single dimensional offsets into
> the block.
>
> And finally, Ruby uses the lists-of-lists approach, in which you have
> only one-dimensional arrays, but every cell of those arrays can be an
> array itself (and so on recursively). Not as efficient as the
> rectangular approach, but it allows for irregularly shaped arrays.

probably worth noting here that narray provides a syntheiss of both, with
copious numerical and array based methods added to boot.

cheers.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| Your life dwells amoung the causes of death
| Like a lamp standing in a strong breeze. --Nagarjuna
===============================================================================

Ara.T.Howard, Oct 11, 2005
7. ### Peter v. N.Guest

Thank you for all the replies! This is really great.

But I still wonder (or play dumb here):

what's the difference between

arr = Array.new(3) { Array.new(3) }

and

arr = Array.new(3, Array.new(3))

Brian Schröder wrote:
> On 11/10/05, Peter v. N. <> wrote:
>
>>Hi all,
>>
>>I'm a Ruby noob so please forgive me...
>>
>>I know there exist "simple" ways (Google's thy friend)
>>to create md arrays with Ruby. But it's somehow cumbersome
>>and it would be nice if it could be done like "array = Array.new(3,3)"
>>-> I know too that this means not the same in Ruby...
>>
>>What I like to know: what led to the decission to do it that way
>>and not like it is done in the C/C++ (Java) languages à la
>>"int[][] arr = new int[3][3]"?

>
>
> you do it the same as in c, you say that you want an array of arrays.
> E.g.
>
> arr = Array.new(3) { Array.new(3) }
>
> which is the same as int[3][3] in c where iirc int[3][3] is not a
> contiguous block of memory but pointers to arrays. If you want a
>
>
>>Maybe because this approach is not strictly oo-oriented? But then,
>>switches and loops in Ruby are neither.

>
>
> In my opinion this has nothing to do with oo versus non oo. Switches
> and loops are signs of imperative programming, which is oppsite to
> functional and logical programming but orthogonal to object oriented
> versus not object oriented.
>
>
>>It's just the devil inside who likes to know about the philosophy
>>about the "why it is done like that" and I'm not bitching about
>>Ruby (by no means).
>>
>>Thank you for a pointer or a short explanation.
>>
>>Greetings,
>>Peter
>>
>>

>
>
> And beware that
> Array.new(3, Array.new(3)) is not the same as Array.new(3) { Array.new(3) }
>
> hope to help,
>
> Brian
>
> --
> http://ruby.brian-schroeder.de/
>
> Stringed instrument chords: http://chordlist.brian-schroeder.de/
>
>

Peter v. N., Oct 11, 2005
8. ### David A. BlackGuest

Hi --

On Wed, 12 Oct 2005, Peter v. N. wrote:

> Thank you for all the replies! This is really great.
>
> But I still wonder (or play dumb here):
>
> what's the difference between
>
> arr = Array.new(3) { Array.new(3) }
>
> and
>
> arr = Array.new(3, Array.new(3))

In the first one, the block is executed once each time to fill up the
array. It's like:

arr = [Array.new(3),Array.new(3),Array.new(3)]

So it's an array of three different arrays.

The second one sets all three initial values to the *same* array.
It's like:

inner = Array.new(3)
arr = [inner,inner,inner]

So you've got an array of three copies of the same object, which of
course has major implications when you modify that object, etc.

David

--
David A. Black

David A. Black, Oct 12, 2005
9. ### Peter v. N.Guest

I got that! Your explanation is clear & simple.

I'm really astonished as how fast everyone responds here.

Thank you all..and wait for more to come from my side ;-)

David A. Black wrote:
> Hi --
>
> On Wed, 12 Oct 2005, Peter v. N. wrote:
>
>> Thank you for all the replies! This is really great.
>>
>> But I still wonder (or play dumb here):
>>
>> what's the difference between
>>
>> arr = Array.new(3) { Array.new(3) }
>>
>> and
>>
>> arr = Array.new(3, Array.new(3))

>
>
> In the first one, the block is executed once each time to fill up the
> array. It's like:
>
> arr = [Array.new(3),Array.new(3),Array.new(3)]
>
> So it's an array of three different arrays.
>
> The second one sets all three initial values to the *same* array.
> It's like:
>
> inner = Array.new(3)
> arr = [inner,inner,inner]
>
> So you've got an array of three copies of the same object, which of
> course has major implications when you modify that object, etc.
>
>
> David
>

Peter v. N., Oct 12, 2005