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

Gurus: I'm need to pull values in from an array into a hash to display details for grand total amounts (see below examples). I thought of putting a loop with the foreach loop.
push @fields, {company_ident => $comp_ident, company => $company, batch_number => $batch_num, effective_date => $effent_date, entry_description => $entry_desc, date_created => $date_crt, prod_number => $prod_num, debits => $debits, credits => $credits}; $sumcredits{$company}+= $credits; #$sumitems{$company}+= $total; }; }; foreach $comp (keys %sumcredits) { print $comp . "\t" . $sumcredits{$comp} . "\n"; };
Here's the output so far:
Disney 22806.00 Tiger Human Fund 32136.97 Little Jerry Inc. 1450.00 Biggens Co. 2329.51 Conservative Fund 12515.38
I was thinking something like this:
foreach my $comps (keys %comps) { print $comps; foreach $comp (keys %sumcredits) { #print $comp . "\t" . $sumcredits{$comp} . "\n"; }; };

Replies are listed 'Best First'.
Re: Query Array from Hash
by crashtest (Curate) on Feb 20, 2010 at 00:51 UTC

    If I understand your objective correctly, I don't think you've picked a good approach for your data structures. You're storing your detail information in @fields, but there is no good way to link your totals back to the details!

    Given the apparent nature of your data - data sets linked together by a common field - I'd think a hash is the way to go. A hash of arrays (HoA), where each hash entry corresponds to a company, and each array entry is a set of transaction details(?). Instead of just keeping totals in a hash (as you're doing with %sumcredits), keep it all in there!

    Something like this (untested):

    my %details_for = (); for (... [your loop beginning here] ...){ my $trans_details = $details_for{$comp_ident}; unless ($trans_details){ $trans_details = []; # first time for this company. # create its array of details. $details_for{$comp_ident} = $trans_details; } # Add to array of trans details for this company push @$trans_details, { company_ident => $comp_ident, company => $company, ... etc., debits => $debits, credits => $credits }; } # Ok, now you've accumulated the data print STDERR Dumper(\%details_for); # just for debugging. # Print the results: foreach my $comp_ident (keys %details_for){ my @trans_details = @{$details_for{$comp_ident}}; my $comp = $trans_details[0]->{'company'}; my $sumcredits += $_->{'credits'} for (@trans_details); # Show the total credits print $comp, "\t", $sumcredits, "\n"; foreach my $trans(@trans_details){ print " " x 3; # indent a little print "effective: ", $trans->{'effective_date'}; print ". created: ", $trans->{'date_created'}; # etc. print "\n"; } }

    This is how I'd approach it. If you want to stick with using an array to keep your transaction details, you could... but you'd have to loop over the entire array to find the transactions for the company you want to print details on, probably with grep:

    foreach $comp (keys %sumcredits) { print $comp . "\t" . $sumcredits{$comp} . "\n"; my @trans_details = grep {$_->{'company'} eq $comp} @fields; # Now loop over @trans_details and print. };
    Depending on the size of your data, I wouldn't really recommend this approach. Conceptually, your data is a HoA (as near as I can tell), so you should represent it as such in Perl.

    Hope this helps. And, all code above is completely untested and probably littered with typos.

      Your the man! This is what I needed. Since I'm still a novice in this, I need little nudges to steer me in the right direction. Thanks for your help.