比较两个数组并找出差异 [英] Comparing two arrays and finding differences

查看:76
本文介绍了比较两个数组并找出差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要比较两个数组并得到差异.

背景:

第一个数组将列出文件夹中的文件.

第二个数组将读取文件的内容并存储在数组中.

第一个数组的输出将是

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::UtilsArray::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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆