# 2 dimensional arrays

**URL:** <https://www.ruby-forum.com/t/2-dimensional-arrays/60588>\
**Category:** Ruby\
**Created:** [May 15, 2006, 11:06pm UTC](https://www.ruby-forum.com/t/2-dimensional-arrays/60588 "2006-05-15T23:06:32Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![jsimone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@jsimone](https://www.ruby-forum.com/u/jsimone)\
**Post date:** [May 15, 2006, 11:06pm UTC](https://www.ruby-forum.com/t/2-dimensional-arrays/60588/1 "2006-05-15T23:06:32Z")

</div>

The 2 dimensional array or table structure is extremely common, but I  
don’t see a simple/standard way to implement this in Ruby. Is there an  
easy way to do this?

---

<div class="post-metadata">

**Author:** ![jsimone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@jsimone](https://www.ruby-forum.com/u/jsimone)\
**Post date:** [May 15, 2006, 11:14pm UTC](https://www.ruby-forum.com/t/2-dimensional-arrays/60588/2 "2006-05-15T23:14:25Z")

</div>

Joe S. wrote:

> The 2 dimensional array or table structure is extremely common, but I  
> don’t see a simple/standard way to implement this in Ruby. Is there an  
> easy way to do this?

One pretty easy way:

irb(main):001:0\> a = [[1, 2, 3] ]  
=\> [[1, 2, 3]]  
irb(main):002:0\> a[0]  
=\> [1, 2, 3]  
irb(main):003:0\> a[0][1]  
=\> 2

-Justin

---

<div class="post-metadata">

**Author:** ![jsimone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@jsimone](https://www.ruby-forum.com/u/jsimone)\
**Post date:** [May 16, 2006, 12:20am UTC](https://www.ruby-forum.com/t/2-dimensional-arrays/60588/3 "2006-05-16T00:20:22Z")

</div>

On May 15, 2006, at 5:06 PM, Joe S. wrote:

> The 2 dimensional array or table structure is extremely common, but I  
> don’t see a simple/standard way to implement this in Ruby. Is  
> there an  
> easy way to do this?
> 
> –  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

A 2-dimensional array is simply an array of arrays. Something like this:

a = Array.new() {Array.new}

Or you could use the Matrix class from “matrix” in the standard library.

---

<div class="post-metadata">

**Author:** ![jsimone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@jsimone](https://www.ruby-forum.com/u/jsimone)\
**Post date:** [May 16, 2006, 3:34pm UTC](https://www.ruby-forum.com/t/2-dimensional-arrays/60588/4 "2006-05-16T15:34:29Z")

</div>

Timothy H. wrote:

> On May 15, 2006, at 5:06 PM, Joe S. wrote:
> 
> > The 2 dimensional array or table structure is extremely common, but I  
> > don’t see a simple/standard way to implement this in Ruby. Is  
> > there an  
> > easy way to do this?
> > 
> > –  
> > Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
> 
> A 2-dimensional array is simply an array of arrays. Something like this:
> 
> a = Array.new() {Array.new}
> 
> Or you could use the Matrix class from “matrix” in the standard library.

A 2 dimensional array as an array of arrays is a lowest common  
denominator. It assumes that I want only to use it as a simple storage  
mechanism. What I want is a 2 dimensional array data structure that has  
powerful operating mechanisms such as sorting. Additionally the way an  
array of arrays is treated in Ruby goes against what is intuitive or  
expected; and it was my understanding that Ruby was supposed to be  
designed to do what “least surprises”.

Here is a simple example.

a = Array.new(){Array.new()}  
b = [9,8,7]  
c = [1,2,3]  
a[0] = b  
a[1] = c

puts a.sort  
=\>[[1,2,3],[9,8,7]]

So this allows a sort across the entire array and it should be noted  
that it does an index step through comparison so [1,1,2] would come  
after [1,1,1]. However this means I am limited to sorting only via this  
mechanism.

Based on Ruby syntax I would find this to be intuitive.

a[0…1][0].sort

The results I would then expect would be  
[[1],[9]]

The results I actually get from this are  
[7,8,9]

What is happening is that in a[0…1][0] a[0…1] is grabbing the subset  
of arrays 0 to 1 and then the second index [0] is indexing back in to  
the subset. What looks like it should be happening is that a[0…1][0]  
is defining the set of the arrays where we wish to retrieve the 0 index.

---

<div class="post-metadata">

**Author:** ![jsimone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@jsimone](https://www.ruby-forum.com/u/jsimone)\
**Post date:** [May 16, 2006, 4:41pm UTC](https://www.ruby-forum.com/t/2-dimensional-arrays/60588/5 "2006-05-16T16:41:58Z")

</div>

> A 2 dimensional array as an array of arrays is a lowest common  
> denominator. It assumes that I want only to use it as a simple storage  
> mechanism.

Aside from a 1-dimensional array using flattened indices, an array of  
arrays is the most basic and common mechanism, because memory is  
1-dimensional. Show me a computer with 2-dimensional memory and I’ll  
write you a better structure.

> What I want is a 2 dimensional array data structure that has  
> powerful operating mechanisms such as sorting. Additionally the way an  
> array of arrays is treated in Ruby goes against what is intuitive or  
> expected; and it was my understanding that Ruby was supposed to be  
> designed to do what “least surprises”.

I think most people find the array of arrays to be fairly intuitive  
(i.e. first index selects a subarray, second index selects an item  
from the subarray), and Ruby holds to that intuition. I would  
nonoffensively suggest that what you are expecting is non-intuitive.

> So this allows a sort across the entire array and it should be noted  
> that it does an index step through comparison so [1,1,2] would come  
> after [1,1,1]. However this means I am limited to sorting only via this  
> mechanism.

You are limited to that sorting mechanism only if you choose to be;  
try using sort\_by and use your own code to determine sort order.

> Based on Ruby syntax I would find this to be intuitive.
> 
> a[0…1][0].sort
> 
> The results I would then expect would be  
> [[1],[9]]
> 
> The results I actually get from this are  
> [7,8,9]

a[0…1] grabs the 0th and 1st item of a. However, in order to return  
multiple values, Ruby uses arrays, so those go right back into an  
array. Then you use [0], and get back the 0th item [7,8,9]. Pretty  
straightforward.

To get the results you want is not terribly difficult: a.collect {  
|x| [x[0]] }

Yes, I’ve also heard that Ruby is intended to be a language of “least  
surprises”, but you can satisfy everyone at the same time. However, it  
is also a language of easy extendability, so if an array of arrays  
does not serve your purposes, or you have a different interpretation  
of the [] operator, it’s trivial to start fleshing out your own  
classes to make it a language of “least surprises for you”.

class Array2D  
def [] (i)  
# …  
end  
def []= (i, x)  
# …  
end  
end

---

<div class="post-metadata">

**Author:** ![jsimone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@jsimone](https://www.ruby-forum.com/u/jsimone)\
**Post date:** [May 16, 2006, 4:42pm UTC](https://www.ruby-forum.com/t/2-dimensional-arrays/60588/6 "2006-05-16T16:42:05Z")

</div>

> Yes, I’ve also heard that Ruby is intended to be a language of “least  
> surprises”, but you can satisfy everyone at the same time.

Ummm… I think I meant you CAN’T satisfy everyone at the same time…

---

<div class="post-metadata">

**Author:** ![jsimone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@jsimone](https://www.ruby-forum.com/u/jsimone)\
**Post date:** [May 16, 2006, 4:45pm UTC](https://www.ruby-forum.com/t/2-dimensional-arrays/60588/7 "2006-05-16T16:45:20Z")

</div>

On Tue, 16 May 2006, Joe S. wrote:

> A 2 dimensional array as an array of arrays is a lowest common denominator.  
> It assumes that I want only to use it as a simple storage mechanism. What I  
> want is a 2 dimensional array data structure that has powerful operating  
> mechanisms such as sorting. Additionally the way an array of arrays is  
> treated in Ruby goes against what is intuitive or expected; and it was my  
> understanding that Ruby was supposed to be designed to do what “least  
> surprises”.

that is widely understood to mean ‘least suprise to matz’. fyi.

> So this allows a sort across the entire array and it should be noted  
> that it does an index step through comparison so [1,1,2] would come  
> after [1,1,1]. However this means I am limited to sorting only via this  
> mechanism.

no, it doesn’t:

harp :~ \> cat a.rb

m = [9,8,7], [1,2,3]

p m.sort\_by{|row| row.last}

p m.sort{|a,b| a[2] \<=\> b[2]}

harp :~ \> ruby a.rb  
[[1, 2, 3], [9, 8, 7]]  
[[1, 2, 3], [9, 8, 7]]

> What is happening is that in a[0…1][0] a[0…1] is grabbing the subset  
> of arrays 0 to 1 and then the second index [0] is indexing back in to  
> the subset. What looks like it should be happening is that a[0…1][0]  
> is defining the set of the arrays where we wish to retrieve the 0 index.

i understand why you might think that - but it doesn’t really make  
sense. if  
what you said were true then this

p a[1][1] #=\> 2

would print an array and not 2. in otherwords if you want the last  
index on a  
2d array to return a column vector then access the elements would always  
require 3 indices! eg. you’d need

p a[1][1][1] #=\> 2

and that would be strange indeed. in addition column wise read access  
requires column wise write access so one would be able to do

a[0…1][0] = a\_new\_column

again, requiring tripple indices to assign elements.

i think you are looking for something like narray, which is on rubyforge  
and  
quite powerful. it supports n-dimensional arrays with compound  
indicies:

harp:~ \> cat a.rb  
require ‘narray’

# 

# short-cuts

# 

```
 t, f = true, false

```

# 

# setup 2x3 array

# 

```
 na = NArray.int 2, 3
 p na

```

# 

# row-size access

# 

```
 p na[t, 0]
 na[t, 0] = 1
 p na[t, 0]
 p na

```

# 

# column-wise access

# 

```
 p na[0, t]
 na[0, t] = 2
 p na[0, t]
 p na

```

# 

# element-wise access

# 

```
 p na[1,2]
 na[1,2] = 42
 p na[1,2]
 p na

```

# 

# many operators are defined

# 

```
 p na[t,2].sort
 p na[0,t].sort
 p na.min
 p na.max
 p na.mean
 p na[(na > 1).where]

```

harp:~ \> ruby a.rb  
NArray.int(2,3):  
[[ 0, 0],  
[0, 0],  
[0, 0] ]  
NArray.int(2):  
[0, 0]  
NArray.int(2):  
[1, 1]  
NArray.int(2,3):  
[[ 1, 1],  
[0, 0],  
[0, 0] ]  
NArray.int(3):  
[1, 0, 0]  
NArray.int(3):  
[2, 2, 2]  
NArray.int(2,3):  
[[ 2, 1],  
[2, 0],  
[2, 0] ]  
0  
42  
NArray.int(2,3):  
[[ 2, 1],  
[2, 0],  
[2, 42] ]  
NArray.int(2):  
[2, 42]  
NArray.int(3):  
[2, 2, 2]  
0  
42  
8.16666666666667  
NArray.int(4):  
[2, 2, 2, 42]

regards.

-a

---

<div class="post-metadata">

**Author:** ![jsimone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@jsimone](https://www.ruby-forum.com/u/jsimone)\
**Post date:** [May 16, 2006, 6:08pm UTC](https://www.ruby-forum.com/t/2-dimensional-arrays/60588/8 "2006-05-16T18:08:56Z")

</div>

Matthew M. wrote:

> > A 2 dimensional array as an array of arrays is a lowest common  
> > denominator. It assumes that I want only to use it as a simple storage  
> > mechanism.
> 
> Aside from a 1-dimensional array using flattened indices, an array of  
> arrays is the most basic and common mechanism, because memory is  
> 1-dimensional. Show me a computer with 2-dimensional memory and I’ll  
> write you a better structure.

That is really besides the point. There are many different types of  
data structures that are intended for a variety of purposes. They  
abstract away from the physical layer to make things happen more easily  
and intuitively in different contexts. The table is a perfect example  
since that provides the type of power I want; however I am only looking  
for only fraction of that power on a very dynamic and very small set of  
data so creating a database would be overkill. And if you think that  
having one dimensional memory limits us from having fast 2 dimensional  
data structures then you really need to take some time to better  
understand how some of these data structures trade memory usage for  
efficiency. Try taking a look out the chunk file format, Lua’s core  
table data structure, or how tables typically work in databases.

> > What I want is a 2 dimensional array data structure that has  
> > powerful operating mechanisms such as sorting. Additionally the way an  
> > array of arrays is treated in Ruby goes against what is intuitive or  
> > expected; and it was my understanding that Ruby was supposed to be  
> > designed to do what “least surprises”.
> 
> I think most people find the array of arrays to be fairly intuitive  
> (i.e. first index selects a subarray, second index selects an item  
> from the subarray), and Ruby holds to that intuition. I would  
> nonoffensively suggest that what you are expecting is non-intuitive.

I agree that it is intuitive when you are selecting a single array with  
the first index. a[0] returns [7,8,9] and a[0][0] returns 7. That is  
not surprising. What is less intuitive is a[0…1][x]. I’m sure it can  
be argued either way and I agree that you can’t satisfy everyone.

> > So this allows a sort across the entire array and it should be noted  
> > that it does an index step through comparison so [1,1,2] would come  
> > after [1,1,1]. However this means I am limited to sorting only via this  
> > mechanism.
> 
> You are limited to that sorting mechanism only if you choose to be;  
> try using sort\_by and use your own code to determine sort order.
> 
> > Based on Ruby syntax I would find this to be intuitive.
> > 
> > a[0…1][0].sort
> > 
> > The results I would then expect would be  
> > [[1],[9]]
> > 
> > The results I actually get from this are  
> > [7,8,9]
> 
> a[0…1] grabs the 0th and 1st item of a. However, in order to return  
> multiple values, Ruby uses arrays, so those go right back into an  
> array. Then you use [0], and get back the 0th item [7,8,9]. Pretty  
> straightforward.
> 
> To get the results you want is not terribly difficult: a.collect {  
> |x| [x[0]] }
> 
> Yes, I’ve also heard that Ruby is intended to be a language of “least  
> surprises”, but you can satisfy everyone at the same time. However, it  
> is also a language of easy extendability, so if an array of arrays  
> does not serve your purposes, or you have a different interpretation  
> of the [] operator, it’s trivial to start fleshing out your own  
> classes to make it a language of “least surprises for you”.

It is not “trivial” to implement all classes. Some classes are actually  
quite complex and time consuming to implement. The point in my post was  
to see if there was currently a “standard” class already in use today.  
For more mature languages these types of structures already exist. I  
enjoy using the Ruby language and find that it certain situations it is  
better than other languages, but I am loathe to reinvent the wheel or  
roll my own for something that I know other people use as well so it may  
well exist already.

> class Array2D  
> def [] (i)  
> # …  
> end  
> def []= (i, x)  
> # …  
> end  
> end

---

<div class="post-metadata">

**Author:** ![jsimone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@jsimone](https://www.ruby-forum.com/u/jsimone)\
**Post date:** [May 16, 2006, 6:30pm UTC](https://www.ruby-forum.com/t/2-dimensional-arrays/60588/9 "2006-05-16T18:30:12Z")

</div>

unknown wrote:

> that is widely understood to mean ‘least suprise to matz’. fyi.

I was using that a little tongue in cheek.

> > So this allows a sort across the entire array and it should be noted  
> > that it does an index step through comparison so [1,1,2] would come  
> > after [1,1,1]. However this means I am limited to sorting only via this  
> > mechanism.
> 
> no, it doesn’t:
> 
> harp :~ \> cat a.rb
> 
> m = [9,8,7], [1,2,3]
> 
> p m.sort\_by{|row| row.last}
> 
> p m.sort{|a,b| a[2] \<=\> b[2]}
> 
> harp :~ \> ruby a.rb  
> [[1, 2, 3], [9, 8, 7]]  
> [[1, 2, 3], [9, 8, 7]]

I have not looked much at how sort\_by is used, but I do see how that can  
be beneficial in some situations. When I stated “such as sorting” above  
that was just one example; I see that I should have given others since  
the sorting piece is apparently available. I am really looking for  
flexibility somewhat similar to a database table but on small dynamic  
sets of data.

> > What is happening is that in a[0…1][0] a[0…1] is grabbing the subset  
> > of arrays 0 to 1 and then the second index [0] is indexing back in to  
> > the subset. What looks like it should be happening is that a[0…1][0]  
> > is defining the set of the arrays where we wish to retrieve the 0 index.
> 
> i understand why you might think that - but it doesn’t really make  
> sense. if  
> what you said were true then this
> 
> p a[1][1] #=\> 2
> 
> would print an array and not 2. in otherwords if you want the last  
> index on a  
> 2d array to return a column vector then access the elements would always  
> require 3 indices! eg. you’d need
> 
> p a[1][1][1] #=\> 2

I was saying that the syntax to include multiple rows a[n…m] was  
handled differently than indexing a single row a[n]. How it was doing  
this was just a conjecture based on the results.

> and that would be strange indeed. in addition column wise read access  
> requires column wise write access so one would be able to do
> 
> a[0…1][0] = a\_new\_column
> 
> again, requiring tripple indices to assign elements.
> 
> i think you are looking for something like narray, which is on rubyforge  
> and  
> quite powerful. it supports n-dimensional arrays with compound  
> indicies:

I will check out narray to see if it fits my needs. Thanks for your  
response.

-joe

> regards.
> 
> -a

---

<div class="post-metadata">

**Author:** ![jsimone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@jsimone](https://www.ruby-forum.com/u/jsimone)\
**Post date:** [May 16, 2006, 7:23pm UTC](https://www.ruby-forum.com/t/2-dimensional-arrays/60588/10 "2006-05-16T19:23:27Z")

</div>

> That is really besides the point. There are many different types of  
> data structures that are intended for a variety of purposes. They  
> abstract away from the physical layer to make things happen more easily  
> and intuitively in different contexts. The table is a perfect example  
> since that provides the type of power I want; however I am only looking  
> for only fraction of that power on a very dynamic and very small set of  
> data so creating a database would be overkill.

My point (too obvious to be stated, I thought) was that everything is  
built up from the simpler. If array of arrays doesn’t do it for ya,  
then you’ll need to write it yourself or find someone else who has  
written what you need.

Someone suggested narray… Haven’t used it myself, so I can’t speak  
for it. Someone else also mentioned the standard Matrix, which as far  
as I’ve seen isn’t any more useful than an array of arrays unless  
you’re using them as mathematical matrices.

> It is not “trivial” to implement all classes.

That, I suppose, depends on the classes and the implementor. 😉
