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

Monks, I have three result files (at the moment) and one reference file. All files are two column , id and name. What i want to do is create hashes for files file1, file2 and file3.
foreach $file (@find) { open (open, "<upload_profile/$file") or die $!}; while (<open>) { ($name, $ID) = (split)...; $data{$file} = {$ID => $name}; } close (open); }
Next i want to take the file 'validate' again two columns ID and name and map this file onto each of the three filex files and print those entries which are present in file1-3. This is the problem
open (ORI, "<validate); while (<ORI>) { ($oriName, $oriID) = (split); for $temp (keys %data) { for $identify ( keys %{ $data{$temp} } ) { print " Match $identify=$data{$temp}{$identify} " if (ex +ists $data{$temp}{$oriID});
Any help would be useful

Replies are listed 'Best First'.
Re: HoH problem
by ikegami (Patriarch) on Nov 07, 2006 at 17:45 UTC
    You don't need two loops because you're looking for a known key.
    open(my $fh, '<', 'validate') or die("Unable to open validation file: $!\n"); while (<$fh>) { my ($name, $id) = (split); for my $file (keys %data) { if (exists $data{$file}{$id}) { print "Found $id in file $file with value $data{$file}{$id}.\ +n"; } } }

    Other problems fixed:

    • Replaced globals with safer lexicals.
    • Replaced 2-arg open with safer 3-arg open.
    • Added error checking for open.
Re: HoH problem
by madbombX (Hermit) on Nov 07, 2006 at 18:31 UTC
    You would also do well to avoid using Perl keywords as your varialbe names (or filehandles in this case). It will be extremely confusing when Perl starts spitting out warnings and errors at you.

    I am referencing: open (open,"<upload_profile/$file") or die $!;

    ikegami fixed this without pointing it out (along with fixing other things). Try using more descriptive filehandles or variable names and stay away from Perl specific keywords for them.

Re: HoH problem
by graff (Chancellor) on Nov 08, 2006 at 02:02 UTC
    Maybe I'm missing something, but it looks to me like you have a problem with your first snippet:
    while (<open>) { ($name, $ID) = (split)...; $data{$file} = {$ID => $name}; }
    In each iteration of that loop, the value of the hash element "$data{$file}" is being replaced by a new anonymous hash, containing a just single "$ID, $name" tuple -- and the previous "$ID, name" are discarded. Don't you want the HoH to have a more than one key in the second-layer hash? I would have expected something like this:
    while (<open>) { ($name, $ID) = (split)...; $data{$file}{$ID} = $name; }
      thanks for those pointers much appreciated