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!"=/