Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

hashes in the Nth dimension

by perlaintdead (Scribe)
on Jan 11, 2014 at 05:13 UTC ( [id://1070226]=perlquestion: print w/replies, xml ) Need Help??

perlaintdead has asked for the wisdom of the Perl Monks concerning the following question:

I'm look for a way to retrieve a value where the depth might vary.
like: func("first second last");
At first i tried a loop involving this general idea:

%meows = { kittehs => { purr => "happy", hiss => "mad", weather => { tailflic => "rain", shaking => "a doosy", }, }, } $tail = $meows{"kittehs"}; $tail = $tail{"weather"}; $tail = $tail{"tailflic"};

but this method of "unraveling" the hash doesn't work and i can't just have a fixed amount of currlies because the depth isn't known.

Replies are listed 'Best First'.
Re: hashes in the Nth dimension
by wazat (Monk) on Jan 11, 2014 at 05:40 UTC

    I'm not sure if I understand your question.

    Your general idea isn't syntactically correct. Is this what you mean?

    use strict; use warnings; my %meows = ( kittehs => { purr => "happy", hiss => "mad", weather => { tailflic => "rain", shaking => "a doosy", }, }, ) sub func { my $h_ref = shift; my $cur = $h_ref; for my $k (@_) { $cur = $cur->{$k} } return $cur; } print $meows{"kittehs"}->{weather}->{tailflic}, "\n"; print func( \%meows, "kittehs", "weather", "tailflic"), "\n"; __END__ rain rain
      my example wasn't the code i was trying to use but yeah basically what i was shooting for
      thanks
Re: hashes in the Nth dimension
by roboticus (Chancellor) on Jan 11, 2014 at 10:31 UTC

    perlaintdead:

    There are multiple approaches you could take, but to choose one, you'd have to know how you want to access your data. If you have a varying list of keys, for example, you could make a subroutine that would unravel the hashes:

    my @keys = qw( kittehs weather tailflic ); my $value = unravel_hash(\%meows, @keys ); sub unravel_keys { my $ref = shift; while (@_) { my $key = shift; return undef if ! exists $ref->{$key}; $ref = $ref->{$key}; } # Ran out of keys, so $ref is the requested value return $ref; }

    Of course, if you have array references mixed in, you'll have to make more complex code to check whether to reference by hash key or array index.

    However, the module Data::Diver already does this for you, so you could just download and install it!

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: hashes in the Nth dimension
by Athanasius (Archbishop) on Jan 11, 2014 at 08:27 UTC

    Here is another approach using the Hash::Flatten module:

    #! perl use strict; use warnings; use Hash::Flatten 'flatten'; my %meows = ( kittehs => { purr => 'happy', hiss => 'mad', weather => { tailflic => 'rain', shaking => 'a doosy', }, }, ); my $flat_meows = flatten(\%meows); my @keys = qw(kittehs weather tailflic); my $new_key = join '.', @keys; printf "\$meows{%s} = %s\n", $new_key, $flat_meows->{$new_key};

    Output:

    18:26 >perl 831_SoPW.pl $meows{kittehs.weather.tailflic} = rain 18:26 >

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2024-04-19 21:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found