merlyn@iwarp.intel.com (Randal Schwartz) (03/18/90)
Well, as I was just gettin' cozy last night (alone... :-) in the waterbed, the following method of doing sparse multidim arrays hit me. After hacking on it for a half hour today, here's what I came up with... ================================================== snip #!/local/merlyn/bin/perl sub get { local(*get'array) = shift; local($get'index); for $get'index ($[..$#_-1) { return undef unless defined $get'array{$_[$get'index]}; *get'array = $get'array{$_[$get'index]}; } $get'array{$_[$#_]}; } sub put { local($put'value) = shift; local(*put'array) = shift; local($put'index); for $put'index ($[..$#_-1) { unless (defined $put'array{$_[$put'index]}) { $put'counter++; $put'array{$_[$put'index]} = eval "\%put'X$put'counter = (); *put'X$put'counter"; } *put'array = $put'array{$_[$put'index]}; } $put'array{$_[$#_]} = $put'value; } sub keys { local(*keys'array) = shift; local($keys'index); for $keys'index ($[..$#_) { return undef unless defined $keys'array{$_[$keys'index]}; *keys'array = $keys'array{$_[$keys'index]}; } keys keys'array; } %c = (); for $i (1..5) { for $j (6..9) { for $k (10..15) { &put("i=$i j=$j k=$k", *c, "I$i", $j*1.001, $k); } } } for $i (sort &keys(*c)) { for $j (sort &keys(*c,$i)) { for $k (sort &keys(*c,$i,$j)) { $value = &get(*c, $i, $j, $k); print "$i $j $k: ", defined $value ? $value : "??", "\n"; } } } ================================================== snip Basically, the three routines are &get(*foo, i1, i2, i3, ...) fetch the assoc-array element $foo{$i1, $i2, $i3, ...} (conceptually). &put($value, *foo, i1, i2, i3 ...) set the assoc-array element $foo{$i1,$i2,$i3,...} to $value. &keys(*foo, i1, i2,....) return an array of the keys at $foo{$i1,$i2,...} (of which $i3 would then be a member...) If someone could take this and clean it up and repost it, I'd be grateful. Hopefully, you can reverse-engineer the code. The method is to have each layer except the last be an assoc-arry of symbol-table entries. If an assoc-array isn't present, but I'm trying to put a value inside it, I create a new one with the funny eval. It worked for the few test cases I threw at it. It *needs* "%foo" defined, as you can see in my test program. I tried putting it in "put" and didn't get any easy success. What it still needs is: documentation, "undef", and bulletproofing. Like I said... I have no immediate need for it, so I'm probably not going to work on it any further, so have at it! @X=split(//,'Just another Perl hacker,');*Y=*X;print @Y; -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/