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
我有一个问题,我似乎找不到答案。
我有一个 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