Your data structure should reflect that.
use strict; use warnings; my %data; my %dates; my %zips; while (<DATA>) { chomp; my ($zip, $amt, $date, $candid) = split; $zips {$zip } = 1; $dates{$date} = 1; $data{$candid}{$zip}{amts}{$date} += $amt; } my @candids = sort keys %data; my @dates = sort keys %dates; my @zips = sort keys %zips; local $, = "\t"; local $\ = "\n"; for my $candid (@candids) { my $table = $data{$candid}; print('CANDID', 'ZIP', (map "MONEY ($_)", @dates)); for my $zip (@zips) { my $row = $table->{$zip}; my @amts = map { $_ || 0 } @{ $row->{amts} }{ @dates }; print($candid, $zip, @amts); } print(''); } __DATA__ 12345 200 11062000 C1234 12345 50 11062000 C1234 67890 50 11072000 D5555 38401 250 11062000 C00003418 77024 200 11062000 C00003418 75711 1000 11072000 C00003418 33480 5000 11072000 C00003418
CANDID ZIP MONEY (11062000) MONEY (11072000) C00003418 12345 0 0 C00003418 33480 0 5000 C00003418 38401 250 0 C00003418 67890 0 0 C00003418 75711 0 1000 C00003418 77024 200 0 CANDID ZIP MONEY (11062000) MONEY (11072000) C1234 12345 250 0 C1234 33480 0 0 C1234 38401 0 0 C1234 67890 0 0 C1234 75711 0 0 C1234 77024 0 0 CANDID ZIP MONEY (11062000) MONEY (11072000) D5555 12345 0 0 D5555 33480 0 0 D5555 38401 0 0 D5555 67890 0 50 D5555 75711 0 0 D5555 77024 0 0
A minor change would cut out "blank" rows and columns if that's what you prefer. Specifically, collect a lists of zips and dates per cand instead one one global list.
In reply to Re: Creating One Table From Several Hashes
by ikegami
in thread Creating One Table From Several Hashes
by bryced1234
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |