From: Robert Klemme Date: 2009-11-20T16:25:10+09:00 Subject: Re: dynamic array? On 19.11.2009 17:53, Marnen Laibow-Koser wrote: > Robert Klemme wrote: >> What are you trying to achieve with this? As far as I can see you are >> mimicking Array behavior with a Hash. So you have created a sparse >> array but not a two dimensional array - which was what the OP wanted >> if I understand him properly. > > Right. The idea was to create a sparse one-dimensional array for the > major axis, then populate it with (sparse or not) one-dimensional arrays > for the minor axis as necessary. Perhaps I should have explained that > in the first place. :) > > I was trying to avoid the pitfall of your LazyM solution, which appears > to use matrix[i, j] instead of matrix[i][j] to address a cell. To my > mind this violates POLS. I don't find that particularly violating POLS. If you want Arrays nested in a Hash you can do this as well irb(main):001:0> matrix = Hash.new {|h,k| h[k] = []} => {} irb(main):002:0> matrix[10][2]=13 => 13 irb(main):003:0> matrix[10][2] => 13 irb(main):004:0> matrix => {10=>[nil, nil, 13]} irb(main):005:0> However, this has bad memory characteristics, especially with large second index values. You could of course instead do irb(main):005:0> matrix = Hash.new {|h,k| h[k] = {}} => {} irb(main):006:0> matrix[10][2] => nil irb(main):007:0> matrix[10][2]=13 => 13 irb(main):008:0> matrix[10][2] => 13 irb(main):009:0> matrix => {10=>{2=>13}} irb(main):010:0> I tend to believe that my solution with a single Hash and arrays as indexes is more efficient although I cannot prove it right now. Personally I would prefer having a single object that encapsulates the storage mechanism away (so you can even change it later). That's more difficult with the addressing scheme (two sets of brackets) you seem to favor: class LazyM2 Proxy = Struct.new :m, :x do def [](y); m.get(x,y) end def []=(y,v); m.set(x,y,v) end end def initialize(default = nil) @h = Hash.new(default) end def [](x) Proxy.new self, x end def get(x,y) @h[[x,y]] end def set(x,y,z) @h[[x,y]]=z end def clear @h.clear end end matrix = LazyM2.new matrix[1][20]=123 p matrix >> As a side note: I'd rather delegate to instead of inherit from Hash. >> The DynamicArray is not a Hash. For example, method #size remains in >> the interface which might lead to surprises. > > Probably not a bad idea. This was seat-of-the-pants code. :) I didn't knew _that_ category of software. Learn something new every day. :-) Cheers robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/