比较两个数组并找出差异 [英] Comparing two arrays and finding differences
问题描述
我需要比较两个数组并得到差异.
背景:
第一个数组将列出文件夹中的文件.
第二个数组将读取文件的内容并存储在数组中.
第一个数组的输出将是
a乙Cd电子
第二个数组的输出将是
a乙C电子
我如何比较这两个有差异的数组?我想要的结局输出是
d
代码如下:
#!/usr/bin/perl使用严格;使用警告;我的 $list = "experiment.sv";我的 $path = "../../../folder1/";我的 $filelist;打开(输出文件,> output.txt");主要的 ();关闭输出文件;子主{我的@array1;opendir ( DIR, $path ) ||die "打开目录 $path 时出错\n";while ( $filelist = readdir (DIR) ) {下一个 if ( $filelist =~ s/\.//g);#/推@array1, $filelist;}关闭 (DIR);我的@array2;open( my $fh, "<", "$path/$list") 或死无法打开文件:$!\n";while(<$fh>) {推@array2, $_;}关闭 $fh;我的@result;foreach 我的 $array2 (@array2) {foreach 我的 $array1 (@array1) {如果 ($array1 !~/$array2/) {push @result, "$array1\n";}}}打印输出文件"",@result;}
有几种方法可以做到这一点,也取决于具体需要什么.
对每个数组使用辅助散列,将存在性检查减少为查找
使用警告;使用严格;使用功能说";子 diff_arys {我的 ($ra1, $ra2) = @_;我的 %in_a1 = 地图 { $_ =>1 } @$ra1;我的 %in_a2 = 地图 { $_ =>1 } @$ra2;我的@not_in_one = grep { 不存在 $in_a1{$_} } @$ra2;我的@not_in_two = grep { 不存在 $in_a2{$_} } @$ra1;返回 (@not_in_one ? \@not_in_one : undef),(@not_in_two ? \@not_in_two : undef);}我的@ary1 = 'a'..'e';# a,b,c,d,e我的@ary2 = ('a'..'d', 'z');# a,b,c,d,z我的 ($not_in_one, $not_in_two) = diff_arys(\@ary1, \@ary2);说@$not_in_one"如果 $not_in_one;说@$not_in_two"如果 $not_in_two;
印刷品
<前>z电子这会发现两种方式的不同,一个数组中的元素而不是另一个数组中的元素.如果你确实知道你只需要一个方向",识别在第一个数组中但不在第二个数组中的东西(从问题看来),然后调整 sub 以便只获得所需的回报.然后代码更少,你可以只返回数组(所以,列表或空)
注意接口的选择:如果没有发现差异,则返回undef
,否则返回arrayref.
这类工作有很好的模块.一个相当全面的是List::Compare.还有 Array::Utils 和 Array::Compare 等等.然后还有更复杂的工具也可以用于此目的,例如 Algorithm::Diff.
I need to compare two array and get differences.
Background:
1st array will list out files in folder.
2nd array will read the content of a file and stored in array.
The output of 1st array will be
a
b
c
d
e
The output of 2nd array will be
a
b
c
e
How I can compare those 2 array that get differences? The finale output that I want is
d
Here is the code:
#!/usr/bin/perl
use strict;
use warnings;
my $list = "experiment.sv";
my $path = "../../../folder1/";
my $filelist;
open ( OUTFILE, ">output.txt" );
main ();
close OUTFILE;
sub main {
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);
my @array2;
open( my $fh, "<", "$path/$list") or die "Failed to open file: $!\n";
while(<$fh>) {
push @array2, $_;
}
close $fh;
my @result;
foreach my $array2 (@array2) {
foreach my $array1 (@array1) {
if ($array1 !~ /$array2/ ) {
push @result, "$array1\n";
}
}
}
print OUTFILE "",@result;
}
There are a few ways to do this, also depending on what exactly is needed.
Using an ancillary hash for each array, to reduce the existence check to a lookup
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;
Prints
z e
This finds difference both ways, elements in one array but not in the other. If you know for fact that you only need it for one "direction," to identify things that are in the first array but not in the second (as it seems from the question), then adjust the sub so to only get needed return. Then there's less code, and you can just return the array (so, a list or empty)
Note the choice for the interface: Return undef
if no difference is found, an arrayref otherwise.
There are good modules for this kind of work. A rather comprehensive one is List::Compare. There are also Array::Utils and Array::Compare, and yet more. And then there are more complex tools that can also be used for this, like Algorithm::Diff.
这篇关于比较两个数组并找出差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!