我需要比较两个数组并得到差异。
背景:
第一个数组将列出文件夹中的文件。
第二个数组将读取文件的内容并存储在数组中。
第一个数组的输出将为
a
b
c
d
e
第二个数组的输出将为
a
b
c
e
我如何比较得到差异的那两个数组?我想要的结局输出是
d
代码如下:
#!/usr/bin/perl
use strict;
use warnings;
my $list = "experiment.sv";
my $path = "../../../folder1/";
my $filelist;
open ( OUTFILE, ">uncompile_test.txt" );
main ();
close OUTFILE;
sub main {
#list file in folder
my @array1;
opendir ( DIR, $path ) || die "Error in opening dir $path\n";
while ( $filelist = readdir (DIR) ) {
next if ( $filelist =~ s/\.//g); #/
push @array1, $filelist;
}
closedir(DIR);
#list file from file
my @array2;
open( my $fh, "<", "$path/$list") or die "Failed to open file: $!\n";
while(<$fh>) {
$_ =~ s/^\s+//g; #/
push @array2, $_;
}
close $fh;
my @result;
foreach my $array2 (@array2) {
foreach my $array1 (@array1) {
if ($array1 !~ /$array2/ ) {
push @result, "$array1\n";
}
}
}
print OUTFILE "",@result;
}
答案 0 :(得分:6)
有几种方法可以做到这一点,这还取决于实际需要什么。
为每个数组使用辅助哈希,以将存在检查减少为查找
use warnings;
use strict;
use feature 'say';
sub diff_arys {
my ($ra1, $ra2) = @_;
my %in_a1 = map { $_ => 1 } @$ra1;
my %in_a2 = map { $_ => 1 } @$ra2;
my @not_in_one = grep { not exists $in_a1{$_} } @$ra2;
my @not_in_two = grep { not exists $in_a2{$_} } @$ra1;
return (@not_in_one ? \@not_in_one : undef),
(@not_in_two ? \@not_in_two : undef);
}
my @ary1 = 'a'..'e'; # a,b,c,d,e
my @ary2 = ('a'..'d', 'z'); # a,b,c,d, z
my ($not_in_one, $not_in_two) = diff_arys(\@ary1, \@ary2);
say "@$not_in_one" if $not_in_one;
say "@$not_in_two" if $not_in_two;
打印
z e
这发现两种方式都不同,一个数组中的元素不同。如果实际上您只需要一个“方向”就可以识别第一个数组中的内容,而不是第二个数组中的内容(从问题中看来),那么调整该子对象就可以简化代码。
请注意接口的选择:如果没有区别,请返回undef
,否则返回arrayref。
有很好的模块可以进行此类工作。 List::Compare是比较全面的一个。还有Array::Utils和Array::Compare,还有更多。然后还有更复杂的工具也可以用于此目的,例如Algorithm::Diff。
答案 1 :(得分:4)
如perldoc -q "difference of"
中所述,您可以像这样获得两个数组的对称差:
my %count;
for my $x (@array1, @array2) {
$count{$x}++;
}
my @difference;
for my $x (keys %count) {
if ($count{$x} == 1) {
push @difference, $x;
}
}
这假定两个数组中都没有重复的元素。
或者,如果您只想查找array2中不存在的array1元素,则可以从第二个数组构建哈希,然后使用该哈希来过滤第一个数组:
my %seen;
$seen{$_} = 1 for @array2;
my @missing = grep !$seen{$_}, @array1;
答案 2 :(得分:1)
我会这样:
use Data::Dumper;
my @array1= (qw(a b c d e f g i ));
my @array2= (qw(a b c e g h i j));
my %missing1, %missing2;
# Create an hash entry (value undef) for every array1 member
@missing1{@array1} = ();
# Delete every array2 member
delete @missing1{@array2};
# and v.v.
@missing2{@array2} = ();
delete @missing2{@array1};
print "Elements of array 1 missing in array 2:\n", Dumper sort keys %missing1;
print "Elements of array 2 missing in array 1:\n", Dumper sort keys %missing2;