From: ara.t.howard@... Date: 2006-05-16T23:42:25+09:00 Subject: Re: 2 dimensional arrays 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