我有这段代码可以将行放入%data
。 DATA中的一行(最后一行)是重复的,因此我不希望将其添加到%data
。在将该行推入app_id
之前,如何检查ci_name
和%data
组合尚不存在?有点像
push .. unless {app_id already exists}
要修改的代码:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %data;
while( <DATA> ) {
chomp;
next if /app_id/;
my ($app_id,$ci_name,$app_name) = split /,/;
push @{$data{$ci_name}}, {app_id => $app_id, app_name => $app_name };
}
print Dumper(\%data);
__DATA__
app_id,ci_name,app_name
1234,hosta7,Managed File Transfer
1235,hosta7,Patrtol
1236,hosta7,RELATIONAL DATA WAREHOUSE
1237,hosta7,Managed File Transfer
1238,hosta7,Initio Application
1239,hosta7,Data Warehouse Operations Infrastructure
2345,hostb,Tableou
2345,hostb,Tableou
您可以将grep()与一个块一起使用,该块检查app_id
是否等于要插入的块。
...
push @{$data{$ci_name}}, {app_id => $app_id, app_name => $app_name } unless grep { $_->{'app_id'} == $app_id; } @{$data{$ci_name}};
...
您可以暂时使用HoH代替HoA。
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
<DATA>; # Skip header.
my %data;
my %seen;
while (<DATA>) {
chomp;
my ($app_id, $ci_name, $app_name) = split /,/;
$data{$ci_name}{$app_id} //= { app_id => $app_id, app_name => $app_name };
}
# Convert HoH to HoA.
$data{$_} = [ values(%{ $data{$_} }) ]
for keys(%data);
print Dumper(\%data);
以上内容保留第一个重复项,并且不保留顺序。将//=
更改为=
以保留最后的重复项。请继续阅读以获取保留订单的解决方案。
以下是在保留订单的同时删除重复项的常用方法:
my %seen;
my @uniq = grep !$seen{$_}++, @values;
我们可以根据需要调整习惯用法。
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
<DATA>; # Skip header.
my %data;
my %seen;
while (<DATA>) {
chomp;
my ($app_id, $ci_name, $app_name) = split /,/;
push @{ $data{$ci_name} }, { app_id => $app_id, app_name => $app_name }
if !$seen{$ci_name}{$app_id}++;
}
print Dumper(\%data);
上面保留了重复项的第一个,并保留了顺序。
这两个解决方案的速度均为O(N),而先前发布的解决方案的速度为O(N 2),因此此解决方案的伸缩性更好。不过,老实说,除非重复很多,否则以前发布的解决方案的实际速度为O(N)。
注意在循环之前如何添加<DATA>
?这比跳过行中任何地方包含app_id
的所有行要好得多!
如果要保留所有记录(从@ikegami改编而来:]
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
<DATA>; # Skip header.
my %data;
while (<DATA>) {
chomp;
my ($app_id, $ci_name, $app_name) = split /,/;
push @{ $data{$ci_name}{$app_id} }, { app_id => $app_id, app_name => $app_name };
}
print Dumper(\%data);
但是最好编写代码:
$data{$ci_name}{$app_id}{$app_name}++;