exists
requires a single array or hash element as its parameter. You have passed it a list of scalar values whose origin has been lost once they have gone through map
.
You could write your test as
if ( grep { exists $oldhash{$_} }, @line[0..2] ) { ... }
but I think there are better ways to write a solution.
I think this does what you want, but with the data you've given it outputs just u
twice. You haven't shown a required output as I requested, so is that right?
I've inverted the keys that you chose for your own %oldhash
so that a case can be rejected immediately just by checking for the existence of the fourth column (s.av
etc.) in the hash.
I've also added use autodie
, as it's essential to check whether an open
has been successful before you go ahead and use data from the file handle, and this avoids checking every case explicity.
Finally I've added chdir 'D:\\'
so that you don't have to prefix the file names with the path for every open
.
The output includes the final "comment" column from new_file.txt
that gave rise to it. I am sure you can alter the print
statement to give the output that you desire.
use strict;
use warnings;
use autodie;
use Data::Dump;
chdir 'D:\\';
open my $old_fh, '<', 'old_file.txt';
my %old_data;
while (<$old_fh>) {
chomp;
my @fields = split /\t/;
$old_data{$fields[1]}{$fields[0]} = $fields[2];
print "@fields\n";
}
close $old_fh;
open my $new_fh, '<', 'new_file.txt';
while (<$new_fh>) {
chomp;
my @fields = split /\t/;
my $new = '';
if (my $list = $old_data{$fields[3]}) {
my @possible = grep defined, @{$list}{@fields[0,1,2]};
$new = $possible[0] if @possible;
}
print join("\t", @fields[0..3], $new, $fields[4]), "\n";
}
The contents of %old_data
after reading the file look like this
(
"s.av" => { A => "u", C => "u" },
"s.bv" => { B => "u" },
"s.cv" => { C => "m" },
)
output
D Db Dc s.av #cols 0 - 2 do not exist in hash
E A Ab d.ef #column 1 exists, but column 3 doesn't, so nothing is done
E A Ac s.av u #col 1 and 3 exist, so the new file will have the value of $oldhash{A}{s.av}
B Bb B s.bv u #col0 and 3 exist, so I'll include the value of $oldhash{B}{s.bv}