简体   繁体   中英

How to compare two arrays in Perl

I have two arrays. I want to find what elements are in the second but not the first, and what elements are in the first but not the second.

Is there any way with out writing multiple loops?

Each array is something like this $array_2d_1

0  ARRAY(0x9929210)
   0  ARRAY(0x98df3d8)
      0  71
      1  22
      2  15
      3  10
      4  51
   1  ARRAY(0x9934900)
      0  91
      1  82
      2  28
      3  11
      4  91

You can't avoid looping. This solution has four loops, but they're not nested.

my %a1 = map { $_ => 1 } @a1;
my %a2 = map { $_ => 1 } @a2;

my @missing_from_a1 = grep !$a1{$_}, @a2;
my @missing_from_a2 = grep !$a2{$_}, @a1;

You can use the module List::Compare for this task:

use strict;
use warnings;
use List::Compare;

my @arr1 = qw/5 8 12 42 99 10/;
my @arr2 = qw/10 20 12 18 99 10/;

my $lc = List::Compare->new( \@arr1, \@arr2 );

my @arr1Only = $lc->get_Lonly;
print "\@arr1 only: @arr1Only\n";

my @arr2Only = $lc->get_Ronly;
print "\@arr2 only: @arr2Only\n";

Output:

@arr1 only: 42 5 8
@arr2 only: 18 20

Hope this helps!

I think you are looking for something like set implementation in perl right. In standard perl there is no set implementation and here is the module in cpan that can achieve what you are trying to solve set . So, we have to find out a way that we can create unique element out of the array, and hash keys in perl is unique. By using hash implementation we can achieved the set implementation. More details you can look up here :

Set Implementation

To take the set difference between two sets, there must be loops involved somewhere. I am assuming you want to avoid writing out the loops every time you need to compute the set difference instead of having an unhealthy aversion to loops .

One simple way would be to abstract away the operation into a subroutine:

#!/usr/bin/env perl

use strict;
use warnings;

main();

sub main {
    my @x = (1, 2, 3, 4, 5);
    my @y = (3, 5, 7, 8, 9);

    for my $sets ( ([\(@x, @y)], [\(@y, @x)]) ) {
        print "@{ set_diff( @$sets ) }\n";
    }
}

sub set_diff {
    my $x = shift;
    my %y = map { $_ => undef } @{ $_[0] };
    return [ grep not( exists $y{$_} ), @$x ];
}

There are also a number of set implementations on CPAN .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM