Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

unknown number of dimensions of a multidimensional hash

by Otogi (Beadle)
on Mar 09, 2006 at 23:10 UTC ( #535551=perlquestion: print w/ replies, xml ) Need Help??
Otogi has asked for the wisdom of the Perl Monks concerning the following question:

This most probably has been answered before but can't come up with the right keys to research it. I want to dynamically create a hash with multiple dimensions (number of dimensions dynamically increase) for example:
$data {$a}{$b} $data {$a}{$b}{$c} $data {$d}{$e}
So as the script is running I could add more dimensions to the initial hash using a subroutine called given the initial  $data{$a} . How do I do that? and how would I read the hash to get the keys and values if I don't know the dimension of the hash. Thank you.

Comment on unknown number of dimensions of a multidimensional hash
Select or Download Code
Re: unknown number of dimensions of a multidimensional hash
by GrandFather (Sage) on Mar 09, 2006 at 23:22 UTC

    The following code is taken from a game engine and manipulates "keys" of the form (\w+\.)+\w+. Each word represents a hash level.

    our %GameState; # The entire game context # looks up a key (passed as the first param) and adds the value # (if provided as second param). Returns a reference to the value # list. sub Entity { my ($key, $value) = @_; return undef if ! defined $key; my $hash = \%GameGlobals::GameState; my @keys = split /\./, $key; map {$_ = lc $_} @keys; while (@keys && defined $hash) { my $key = shift @keys; if (@keys) { $hash->{$key} = {} if ! exists $hash->{$key}; $hash = $hash->{$key}; } else { $hash->{$key} = [] if ! exists $hash->{$key}; push @{$hash->{$key}}, $_[1] if defined $value; return \$hash->{$key}; } } }

    DWIM is Perl's answer to Gödel
Re: unknown number of dimensions of a multidimensional hash
by duff (Vicar) on Mar 10, 2006 at 00:47 UTC

    Another thing you can do is use concatenated keys rather than a multidimensional data structure. (I don't know how critical the hierarchical nature is to your problem solution) That is, instead of:

    $data {$a}{$b} $data {$a}{$b}{$c} $data {$d}{$e}
    you would use
    $data{join "\0", $a, $b} $data{join "\0", $a, $b, $c} $data{join "\0", $d, $e}
    Then to access the keys you'd use your standard keys operator:
    for (keys %data) { # you could do something with $data{$_} directly, # or if you need access to the individual keys ... my @keys = split /\0/; # ... }
    The main caveat is that your "key separator" should be something that doesn't appear in your keys. I chose "\0" in this example assuming that your keys aren't likely to contain NUL bytes.
Re: unknown number of dimensions of a multidimensional hash
by Anonymous Monk on Mar 10, 2006 at 00:47 UTC

    If the hash is not ragged, you simply know its dimensionality. If you somehow lose this information

    sub hashfirst { $_[0]->{($_) = keys %{$_[0]}} } sub shape { my $h = shift; my @s; for (;'HASH' ne ref $h; $h = hashfirst($h)) { push @s, scalar(keys %$h); } @s }

    may help you remember. This feels like an X-Y question.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://535551]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (6)
As of 2015-07-04 23:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (60 votes), past polls