Perl:重复键不覆盖哈希

Perl: duplicate keys not overwriting in hash

我有一个问题,我似乎找不到答案。

我有一个 CSV 文件,其中包含不同个人的绩效记录。假设每个人只有一个记录,但是,有些人有多个记录,其中包含不同的信息。我想将第一个文件与另一个也有个人列表的文件进行比较,尽管我只想比较文件 1 中的个人是否在文件二中也有记录(文件 2 没有重复项)。个人的 ID 是唯一的。

文件 1 的示例:

ID number      A       B     C            D
4011NM16001    apple   24    sunday       2016-01-01
4011NM16001    apple   16    wednesday    2016-01-01
4012NM15687    pear    16    sunday       2015-04-19
4012NM15002    banana  8     monday       2015-09-09
4012NM14301    peach   10    wednesday    2014-03-18
4012NM14301    peach   18    wednesday    2014-03-18

我打开了第一个文件并尝试将数据放入散列(如果我理解正确的话,更确切地说是散列和数组的组合)以删除重复项,使用 ID 作为唯一钥匙。但是,它没有覆盖具有相同 ID 的条目,它似乎仍然添加它,所以我仍然得到重复的记录。

我想看这个:

ID number
4011NM16001
4011NM15687
4012NM15002
4012NM14301

但我仍然看到这个:

ID number      
4011NM16001    
4011NM16001    
4012NM15687    
4012NM15002    
4012NM14301    
4012NM14301    

我是不是在我的代码中输入了错误的东西,或者我没有正确使用散列?我对 Perl 还是个新手,所以我使用了以前程序的一部分并尝试边学边学..

#!/usr/bin/env perl

use DBI;

use strict;
use warnings;

my $file1  = 'location1.csv';   #file1 containing records with duplicates
my $exists = 'location3.csv';  #output file with unique IDs that will be compared to file2

open (EXISTS, ">$exists") or die "Cannot open $exists";
    print EXISTS "ID number\n";

open (FILE1, "$file1") or die "Cannot open $file1";

while (<FILE1>){

    my %file1;

    my $line = $_;
    $line =~ s/\s*$//g;

    my ($ID, $a, $b, $c, $d) = split('\,', $line);
    next if !$ID or substr($ID,0,2) eq 'ID';

    $file1{$ID}[0]=$ID;  #unique ID number
    $file1{$ID}[1]=$a;   #record a
    $file1{$ID}[2]-$b;   #record b
    $file1{$ID}[3]=$c;   #record c
    $file1{$ID}[4]=$d;   #record d

    print EXISTS "$file1{$ID}[0]\n";
}

exit;

您正在为每个输入行打印行,而不仅仅是不存在的行。 将作业段落前的print移到

print EXISTS "$ID\n" unless exists $file1{$ID};

除了你还需要在之外声明散列 while循环,否则循环的每次迭代都在处理一个新的空哈希

这是您的代码版本,它使用最佳实践 Perl 并生成您想要的结果。请注意,我不得不更改输入文件的格式 location1.csv,因为您显示的值不包含任何逗号

#!/usr/bin/env perl

use strict;
use warnings;

my $file1  = 'location1.csv';    # file1 containing records with duplicates
my $exists = 'location3.csv';    # output file with unique IDs that will be compared to file2

open my $exists_fh, '>', $exists or die qq{Unable to open "$exists" for output: $!};
print $exists_fh "ID number\n";

open my $file1_fh, '<', $file1 or die qq{Unable to open "$file1" for input: $!};
<$file1_fh>; # skip header line

my %file1;

while ( <$file1_fh> ) {

    next unless /\S/; # Skip blank lines

    s/\s+\z//;

    my @fields = split /,/;
    my $id = $fields[0];

    next if $file1{$id}; # Skip this record if the ID is already known

    $file1{$id} = \@fields;

    print $exists_fh "$id\n"
}

输出

ID number
4011NM16001
4012NM15687
4012NM15002
4012NM14301