http://www.perlmonks.org?node_id=585718


in reply to Re^2: hash of hashes
in thread hash of hashes

Data::Dumper is your friend. I suspect you will find that if you Dump out %data between your first loop and your second, that you will find that you're storing more than the last line of each file. However strict is even more your friend, and could have saved you the time in posting on here.

If your second loop is a direct cut-n-paste then your error should be easily fixed. The following line:

print "$id=$data{$file}{$id} ";

Should probably be:

print "$role=$data{$file}{$role} ";

If you were using strict, Perl would have told you about this.

The following code works for me.

use strict; my %data; foreach my $file (@ARGV) { print "file: $file\n"; open (LOOKUP, "$file") or die $!; while (<LOOKUP>) { chomp; my ($name, $id) = (split m{\t})[3, 4]; $data{$file}{$id} = $name; } close (LOOKUP); } for my $file ( keys %data ) { print "$file: "; for my $role ( keys %{ $data{$file} } ) { print "$role=$data{$file}{$role} "; } print "\n"; }

Be aware that if any id is repeated in the file for a different name, then you will only get the last unique pair. For example if your file contains:

xxx yyyy Fred 4 zzzz wwww James 4

Then you will only get the James => 4 pairing and Fred will be lost. If this is a problem, then you'll need to use an array reference:

use strict; my %data; foreach my $file (@ARGV) { print "file: $file\n"; open (LOOKUP, "$file") or die $!; while (<LOOKUP>) { chomp; my ($name, $id) = (split m{\t})[3, 4]; push @{$data{$file}{$id}}, $name; } close (LOOKUP); } for my $file ( keys %data ) { print "$file: "; for my $role ( keys %{ $data{$file} } ) { for my $name ( @{$data{$file}{$role}} ) { print "$role=$name "; } } print "\n"; }

Hope this helps.