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

Hi, I need convert 'associated lists' into a matrices that is accumulative of integers. Please help! I have searched high and dry and could not find a solution. Its making my hair fall out this week..
id1 id2 int 208 10000 1 208 10000 7 207 10000 3 8517 1147 1 3551 1147 2 id1\id2 1147 10000 207 0 3 208 0 8 3551 1 0 8517 1 2
RESOLVED RESOLVED RESOLVED
20x20-NMS parsers # cat list2 d1 id2 int HAT KNIFE 1 HAT KNIFE 7 BALL KNIFE 3 CAT CLOTH 1 DOG CLOTH 2 20x20-NMS parsers # cat test2.list | perl test2.pl $matrix{CAT}{CLOTH} = 1 $matrix{DOG}{CLOTH} = 2 $matrix{HAT}{KNIFE} = 8 $matrix{BALL}{KNIFE} = 3 Delete Ball $matrix{CAT}{CLOTH} = 1 $matrix{DOG}{CLOTH} = 2 $matrix{HAT}{KNIFE} = 8 Match the letter "O" DOG yep, HAT is there! Print Matrix CLOTH KNIFE CAT 1 0 DOG 2 0 HAT 0 8 Done! my %matrix; while (<>) { my ($id1, $id2, $int) = split; $matrix{$id1}{$id2} += $int; } foreach $key1 (keys %matrix) { foreach $key2 (keys %{%matrix->{$key1}}) { print "\$matrix{$key1}{$key2} = $matrix{$key1}{$key2} +"; } print"\n"; } # delete key print "Delete Ball\n"; delete ($matrix{"BALL"}); foreach $key1 (keys %matrix) { foreach $key2 (keys %{%matrix->{$key1}}) { print "\$matrix{$key1}{$key2} = $matrix{$key1}{$key2} "; } print"\n"; } # Match print "Match the letter \"O\"\n"; foreach $key1 (keys %matrix) { foreach $key2 (keys %{%matrix->{$key1}}) { @match = grep (/O/i, $key1); print "@match"; } print"\n"; } # check for key existence if (exists($matrix{"HAT"})) { print "yep, HAT is there!\n"; } # Print Matrix print "Print Matrix\n"; my @down = keys %matrix; my @across = do {my %s; grep {!$s{$_}++} map {keys %$_} values %matrix +}; my $l = 0; $l < length ($_) and $l = length $_ for @down, @across; print " " x $l; printf " %-${l}s", $_ for @across; print "\n"; foreach my $d (@down) { printf "%-${l}s", $d; printf " %${l}d", $matrix{$d}{$_} || 0 for @across; print "\n"; } print"Done!\n";

Replies are listed 'Best First'.
Re: Associated lists to matrices - and accumalted integers
by JavaFan (Canon) on Nov 06, 2009 at 14:43 UTC
    You probably want hashes instead of arrays. Here's how I would do it, assuming three integers per line:
    my %data; while (<>) { my ($id1, $id2, $int) = split; $data{$id1}{$id2} = $int; }
      Hi, thanks. Sorry, from that I still dont get how I can parse a file like this..
      id1 id2 int HAT KNIFE 1 HAT KNIFE 7 BALL KNIFE 3 CAT CLOTH 1 DOG CLOTH 2
      To produce a table like this (notice KNIFE and HAT total is 8). Its 2am here, and would love to get this down else my wife is going to kill be if Im stuck on this all weekend. So your help much appreciated, first time I have asked for help like this.
      CLOTH KNIFE BALL 0 3 HAT 0 8 DOG 1 0 CAT 1 2
        Change the second = in my code to +=.