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

I have an hash which I printed using Dumper.
$VAR1 = { 'comp1' => { 'cmd2' => [ [ 'test2', 'type1', 'view1' ] ], 'c +md1' => [ [ 'test1', 'type1', 'view1' ], [ 'test2', 'type1', 'view1' +] ] } };
How will I traverse thru this and get the element one by one, cmd1, test1, type1 etc.. individually.

Thanks

Replies are listed 'Best First'.
Re: how to traverse thru this hash?
by japhy (Canon) on Nov 03, 2005 at 17:07 UTC
    Assuming the hash is named %instructions:
    for my $computer (keys %instructions) { my $commands = $instructions{$computer}; for my $comm (keys %$commands) { my $argument_sets = $commands->{$comm}; for my $args (@$argument_sets) { my @values = @$args; print "$computer: $comm: [@values]\n"; } } }
    That should print
    comp1: cmd2: [test2 type1 view1] comp1: cmd1: [test1 type1 view1] comp1: cmd1: [test2 type1 view1]
    unless I made a mistake. The code is untested but looks ok to me.

    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
      Is there any benefit to using "for" instead of "foreach", or is it just a style thing?
        My fingers are saved some work? Honestly, 'for' and 'foreach' are interchangeable in Perl syntax. Just read perlsyn.

        Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
        How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: how to traverse thru this hash?
by wfsp (Abbot) on Nov 03, 2005 at 17:27 UTC

    Here's my go.

    #!/bin/perl5 use strict; use warnings; my $v = { 'comp1' => { 'cmd2' => [ [ 'test2', 'type1', 'view1' ] ], 'cmd1' => [ [ 'test1', 'type1', 'view1' ], [ 'test2', 'type1', 'view1' ] ] } }; for my $k1 (sort keys %{$v}){ print "$k1\n"; for my $k2 (sort keys %{$v->{$k1}}){ print " $k2\n"; for my $a1 (@{$v->{$k1}{$k2}}){ for my $a2 (@{$a1}){ print " $a2\n"; } print "-" x 20, "\n"; } } } __DATA__ ---------- Capture Output ---------- > "C:\Perl\bin\perl.exe" _new.pl comp1 cmd2 test2 type1 view1 -------------------- cmd1 test1 type1 view1 -------------------- test2 type1 view1 -------------------- > Terminated with exit code 0.

    Tested ;-)

Re: how to traverse thru this hash?
by szbalint (Friar) on Nov 03, 2005 at 17:25 UTC
    A bit more general approach to list all keys and strings in this complex structure:

    my $VAR1 = { 'comp1' => { 'cmd2' => [ [ 'test2', 'type1', 'view1' ] ], 'cmd1' => [ [ 'test1', 'type1', 'view1' ], [ 'test2', 'type1', 'view1' ] ] } }; my $array = []; sub foo { my ($ref,$array) = @_; if (ref $ref eq 'ARRAY') { foreach my $ret (@{$ref}) { if (ref $ret ne '') { foo($ret,$array); } else { push @{$array},$ret; } } } elsif (ref $ref eq 'HASH') { foreach my $ret (keys %{$ref}) { if (ref $ref->{$ret} ne '') { push @{$array}, $ret; foo($ref->{$ret},$array); } else { push @{$array},$ref->{$ref}; } } } } foo($VAR1,$array); print " @{$array} \n";


    I know the code is ugly, i tried to code fast and this ends up from it. Please point out mistakes politely, thank you.