Вопрос:

Сравнивая два массива и получай различия

perl

32 просмотра

3 ответа

32 Репутация автора

Мне нужно сравнить два массива и получить различия.

Фон:

1-й массив будет перечислять файлы в папке.

2-й массив будет читать содержимое файла и сохраняться в массиве.

Выход 1-го массива будет

a
b
c
d
e

Выход 2-го массива будет

a
b
c
e

Как я могу сравнить те 2 массива, которые получают различия? Окончательный вывод, который я хочу, это

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;  

}
Автор: daffodil Источник Размещён: 12.06.2019 06:28

Ответы (3)


1 плюс

36828 Репутация автора

Есть несколько способов сделать это, также в зависимости от того, что именно нужно.

Использование вспомогательного хэша для каждого массива, чтобы свести проверку существования к поиску

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';
my @ary2 = ('a'..'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
е

Это находит разницу в обоих направлениях, элементы в одном массиве, но не в другом. Если вы точно знаете, что вам это нужно только для одного «направления», чтобы идентифицировать вещи, которые находятся в первом массиве, но не во втором (как это видно из вопроса), то настройте подпрограмму для этого, и код станет проще.

Обратите внимание на выбор интерфейса: верните, undefесли различий не обнаружено, иначе - arrayref.

Есть хорошие модули, которые делают это и многое другое. Весьма исчерпывающим является List :: Compare . Есть также Array :: Utils и Array :: Compare , и еще больше. И еще есть более сложные инструменты, которые также могут быть использованы для этого, например, Algorithm :: Diff .

Автор: zdim Размещён: 12.06.2019 07:02

2 плюса

67401 Репутация автора

Как объяснено выше 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;
    }
}

Это предполагает, что ни в одном массиве нет повторяющихся элементов.

В качестве альтернативы, если вы хотите найти только элементы array1, которых нет в array2, вы можете создать хеш из второго массива и использовать его для фильтрации первого массива:

my %seen;
$seen{$_} = 1 for @array2;
my @missing = grep !$seen{$_}, @array1;
Автор: melpomene Размещён: 12.06.2019 07:03

1 плюс

576 Репутация автора

Я бы сделал это так:

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;
Автор: Skeeve Размещён: 12.06.2019 07:34
Вопросы из категории :
32x32