Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Dereference an Array of Hashes

by dirtdog (Scribe)
on Apr 25, 2012 at 16:05 UTC ( #967102=perlquestion: print w/replies, xml ) Need Help??
dirtdog has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, I've updated the code snippet so hopefully it's more clear. I'm stuck trying to dereference an array of hashes. Each key has 2 values (normally a hash consists of one key and one this is confusing me a little bit.

For example, I have several managers (the key) that have 2 values for each ..."total events" and "total updates"

my @mans = qw / Joe Mike Rich /; my @tot_updates = qw /12 7 17 /; my @tot_events = qw /45 14 10 /; for (@mans) { push( @{$managers{$_}}, shift@tot_updates); push( @{$managers{$_}}, shift@tot_events); } for $t ( $#managers ) { for $b ( keys %{$managers[$t]}) { print "$t and $b is $managers[$t]{$b}\n"; } }

Pushing the values onto the array works fine i believe. It's dereferencing that's not working. I'm totally confused how to dereference this...I'd like the output to be: manager: value1(total updates) value2(total events) Joe 12 45 Mike 7 14 Rich 17 10 Please help if you can..I would really appreciate it greatly

Replies are listed 'Best First'.
Re: Dereference an Array of Hashes
by kennethk (Abbot) on Apr 25, 2012 at 16:22 UTC

    While your code snippet could use some more context, I think your issue is that the outer for loop of your output is looking at @managers but your assignment is using %managers. You should get your expected result with

    push( @{$managers{$mgr}}, $sub_tot_upd_by_mgr); push( @{$managers{$mgr}}, $sub_tot_events_by_mgr); for my $t ( keys %managers ) { for my $b (0 .. $#{$managers{$t}}) { print "$t and $b is $managers{$t}[$b]\n"; } }

    This type of variable confusion could be quickly diagnosed with strict; see Use strict warnings and diagnostics or die. Also note $b is a special variable in the context of sort, and should generally be avoided for normal usage; see $b.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: Dereference an Array of Hashes
by 2teez (Priest) on Apr 25, 2012 at 19:18 UTC

    Without taking anything away from what the last poster said, though use strict and use warnings are not commandment cut in stones, however, (they) will help point out errors in codes!

    You could use Data::Dumper or Data::Dump to print your data structure, like this:

    use warnings; use strict; use Data::Dump qw(dump); use Data::Dumper; my @mans = qw / Joe Mike Rich /; my @tot_updates = qw /12 7 17 /; my @tot_events = qw /45 14 10 /; my %managers; for (@mans) { push( @{$managers{$_}}, shift@tot_updates); push( @{$managers{$_}}, shift@tot_events); } dump(\%managers); print Dumper(\%managers);

    Dump Output:

    { Joe => [12, 45], Mike => [7, 14], Rich => [17, 10]}

    Dumper Output:
    $VAR1 = { 'Joe' => [ '12', '45' ], 'Rich' => [ '17', '10' ], 'Mike' => [ '7', '14' ] };

    And if you don't like the printed display, atleast you have an idea of what to parse. It really a good way to cheat parsing data structure in Perl

    You could also check perldoc perldsc a good Perl Data Structure Cookbook tutorial

Re: Dereference an Array of Hashes
by Marshall (Monsignor) on Apr 26, 2012 at 20:09 UTC
    Your question: "array of hashes" did not match up with the code. There is that and then there is Hash of Array.

    I'll show both ways with some slightly different coding. The Array of Hash roughly corresponds to the C "array of structure". If you don't need to randomly access different managers, then this is a good way - works out well if you are always processing managers as a group. Also maintains the order of the records if that winds up being needed.

    When building these things, also note that curly braces {} and brackets [] mean "allocate new anon hash or array memory". The value of such a thing is a reference to either newly allocated hash or an array memory. This allows the code to look a bit "cleaner", or at least I think so in this particular case.

    What kind of data struct you use depends upon how you intend to process the data. And there are variants like Hash of Hash, etc.

    Oh, @{$managers{$manager}}, the extra set of curly braces are needed, (instead of @$managers{$manager} to make it clear what the @ is operating upon. Here the @ operates on the value of $managers{$manager}, which is an array reference. A "Hash of Array" means a hash key that has as a value, an array reference. You have to use the hash key to get the hash value and then deference that hash value (which is a reference to an array) to get the actual "data".

    #!/usr/bin/perl -w use strict; use Data::Dumper; my @mans = qw / Joe Mike Rich /; my @tot_updates = qw /12 7 17 /; my @tot_events = qw /45 14 10 /; my @managers; while (@mans) { push @managers, { manager => shift @mans, tot_updates => shift @tot_updates, tot_events => shift @tot_events }; } foreach my $href (@managers) { print "$href->{manager} $href->{tot_updates} ". "$href->{tot_events}\n"; } print Dumper \@managers; ####### or ###### Hash of Array ### @mans = qw / Joe Mike Rich /; @tot_updates = qw /12 7 17 /; @tot_events = qw /45 14 10 /; my %managers; while (@mans) { $managers{shift @mans} = [ shift @tot_updates, shift @tot_events]; } foreach my $manager (keys %managers) { print "$manager @{$managers{$manager}}\n"; } print Dumper \%managers; __END__ ## Array of Hash ### Joe 12 45 Mike 7 14 Rich 17 10 $VAR1 = [ { 'tot_events' => '45', 'tot_updates' => '12', 'manager' => 'Joe' }, { 'tot_events' => '14', 'tot_updates' => '7', 'manager' => 'Mike' }, { 'tot_events' => '10', 'tot_updates' => '17', 'manager' => 'Rich' } ]; ########## Hash of Array #### Joe 12 45 Rich 17 10 Mike 7 14 $VAR1 = { 'Joe' => [ '12', '45' ], 'Rich' => [ '17', '10' ], 'Mike' => [ '7', '14' ] };

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://967102]
Approved by kennethk
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (3)
As of 2017-02-22 04:28 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (324 votes). Check out past polls.