On Tue, 16 May 2006, Joe Seeley 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.

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

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


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

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
-- 
be kind whenever possible... it is always possible.
- h.h. the 14th dali lama