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

hi I am trying to get the name of all the customer, But i am bit lost looking for help,
use strict; use warnings; my %h; push @{$h{CUST}}, [ { NAME => 'Mr.y', ADD => 'Hell', } ]; push @{$h{CUST}}, [ { NAME => 'Mr.z', ADD => 'Hell', } ]; push @{$h{ADMIN}}, [ { NAME => 'Mr.x', ADD => 'Hell', } ]; my $name; my $val = $h{CUST}; my $i = 0; for($i, $i<@$val, $i++) { my $hash = $val->[$i]; foreach(@$hash) { print $_->{NAME}; } }
Cheers

Replies are listed 'Best First'.
Re: get value of hash hold by array and array hold by another hash
by Marshall (Canon) on Aug 24, 2010 at 03:38 UTC
    I think your data structure is not quite what you intended. When you make a more complex data structure, Dumper is your friend! One level of array is not necessary and I modified you code to take it out (run Dumper) on your code to see the difference. You were making an array of anon array references to anon hash references where each anon array only had one anon hash reference instead of simply an array of anon hash references.

    @{$h{CUST}} is an array of hash references. Just take each hash reference and de-reference the NAME parameter.

    #!/usr/bin/perl -w use strict; use Data::Dumper; my %h; push @{$h{CUST}}, { NAME => 'Mr.y', ADD => 'Hell', }; push @{$h{CUST}}, { NAME => 'Mr.z', ADD => 'Hell', }; push @{$h{ADMIN}}, { NAME => 'Mr.x', ADD => 'Hell', }; print Dumper \%h; foreach my $href ( @{$h{CUST}}) { print " CUST NAME: $href->{NAME} \n"; } __END__ $VAR1 = { 'ADMIN' => [ { 'NAME' => 'Mr.x', 'ADD' => 'Hell' } ], 'CUST' => [ { 'NAME' => 'Mr.y', 'ADD' => 'Hell' }, { 'NAME' => 'Mr.z', 'ADD' => 'Hell' } ] }; CUST NAME: Mr.y CUST NAME: Mr.z
    Update: Just wanted to show a couple of examples of how to print the OP's original structure. This C style for loop is not necessary. I guess toolic and I were composing our answers at the same time. The main thing is that we both got rid of an unnecessary level of de-referencing and although that is very, very important, proper use of Perl iterator operators is the reason that the "print" code got so much easier.
    #one way for initial structure foreach my $aref ( @{$h{CUST}}) { print " CUST NAME: $aref->[0]->{NAME} \n"; } #another way for initial structure foreach my $href (map{$_->[0]} @{$h{CUST}}) { print " CUST NAME: $href->{NAME} \n"; }
Re: get value of hash hold by array and array hold by another hash
by toolic (Bishop) on Aug 24, 2010 at 03:43 UTC
    If you can simplify your data structure, you can simplify your code:
    use strict; use warnings; my %h; push @{$h{CUST}}, { NAME => 'Mr.y', ADD => 'Hell', } ; push @{$h{CUST}}, { NAME => 'Mr.z', ADD => 'Hell', } ; push @{$h{ADMIN}}, { NAME => 'Mr.x', ADD => 'Hell', } ; my $val = $h{CUST}; for my $href (@{ $val }) { print "$href->{NAME}\n"; } __END__ Mr.y Mr.z
Re: get value of hash hold by array and array hold by another hash
by TomDLux (Vicar) on Aug 24, 2010 at 05:15 UTC

    What they said.

    But also, you're using commas in your C-style loop, where the correct delimiter is semi-colons. Without semi-colons, it's being interpreted as some non-C-ish for-loop, where you want to run three commands in sequence: $i, $i<@$val, and $i++, ( the first two presumably for side-effects) and use the value of the third.

    I haven't used a C-ish loop in years ... not relevant in Perl. If you DO want to increment over the indices, the simplest way is using the range operator:

    for my $index ( 0 .. @{$val} -1 ) { do_stuff() }

    But mostly for loops are for iterating over arrays or lists, possibly the keys from hashes

    As Occam said: Entia non sunt multiplicanda praeter necessitatem.

Re: get value of hash hold by array and array hold by another hash
by TomDLux (Vicar) on Aug 24, 2010 at 05:32 UTC

    By the way, if you want to initialize data structures, you can do it directly, you don't need to push values on. But maybe you were just doing that since you weren't getting output, and worried it might be something about the initialization. You clearly have a handle on anonymous arrays and hashes.

    my %h = ( CUST => [ { NAME => 'Mr. y', ADD => 'Hell' }, { NAME => 'Mr. z', ADD => 'Dell' }, ], ADMIN => [ { NAME > 'Mr. x', ADD => 'Hell' }, ], );

    I use trailing commas and leave the closing brace on the next line, to make it easier to add more entries.

    update ... oops, left a typo '/' in the wrong place overnight

    As Occam said: Entia non sunt multiplicanda praeter necessitatem.