Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Populating hash keys

by dda (Friar)
on Oct 03, 2003 at 13:06 UTC ( [id://296212] : perlquestion . print w/replies, xml ) Need Help??

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

Dear Monks, please take a look at this code:
my $href; my @keys = qw (1,2,3); $href->{1}->{2}->{3} = 'somedata'; # keys hardcoded
Is it possible to automate the 'conversion' of @keys array to a set of hash keys? Suppose, I have an array and corresponding data, and I neeed to create a composite hash key from the array. Please advise.


Replies are listed 'Best First'.
Re: Populating hash keys
by liz (Monsignor) on Oct 03, 2003 at 13:24 UTC
    my @keys = qw (1,2,3);
    should probably either be:
    my @keys = (1,2,3); # or (1..3) if they're consecutive numbers
    my @keys = qw(1 2 3);

    But to get back to your question:

    use Data::Dumper; my @keys = (1,2,3); my $href = 'somedata'; $href = {pop(@keys) => $href} while @keys; #$href = {$_ => $href} foreach reverse @keys; # alternate solution, if + @keys is constant or needed later print Dumper( $href ); __END__ $VAR1 = { '1' => { '2' => { '3' => 'somedata' } } };


    Added (1..3), suggested by broquaint

    Added foreach reverse alternative, suggested by myself ;-)

Re: Populating hash keys
by broquaint (Abbot) on Oct 03, 2003 at 13:29 UTC
    You can find a variety of solutions to dynamic hash population at setting hash keys by array e.g
    use Data::Dumper; ## japhy's solution, with a style contribution from Juerd my @keys = qw( this that those ); my $node = \\my %hash; $node = \$$node->{$_} for @keys; $$node = 'value'; print Dumper(\%hash); __output__ $VAR1 = { 'this' => { 'that' => { 'those' => 'value' } } };


      Thanks broquaint. How did you manage to find exactly the same question? Please share with me what to enter in Super Search input box -- next time I'll use this technique :).


        Since I contributed to the thread I vaguely remembered what was contained within the replies, so I just searched for and of Juerd's threads containing the string 'style' as I roughly remembered what he'd written in his reply to japhy. That's about the only way I usually find anything with Super Search, but that's just me ;)


Re: Populating hash keys
by zby (Vicar) on Oct 03, 2003 at 13:24 UTC
    Update: Reading liz response I realized that I've done a reverse task to what was asked for.

    Here is a recursive subroutine for that:

    sub applypath{ my($val, $index, @path) = @_; if(!defined($index)){ return $val; } return applypath($val->{$index}, @path); }
    You might add some parameter checking if you need it and of course an iterative subroutine would be more efficient if you are into optimisation.

    By the way I feel that my @keys = qw (1,2,3) is not exactly what you wanted to write as it is equivalent to my @keys = "1,2,3". Read about the qw operator on the perlop manpage (perldoc perlop).

      zby, thanks for your note about qw :)


Re: Populating hash keys
by simonm (Vicar) on Oct 03, 2003 at 15:48 UTC
    You could try the wrapper functions provded by Data::DRef:
    use Data::DRef qw( get_value_for_keys set_value_for_keys ); my @keys = (1,2,3); my $href = {}; # to store value set_value_for_keys( $href, 'somedata', @keys ); # to fetch value my $data = get_value_for_keys( $href, @keys );