How can I compare arrays in Perl?

后端 未结 12 2031
隐瞒了意图╮
隐瞒了意图╮ 2020-12-06 18:54

I have two arrays, @a and @b. I want to do a compare among the elements of the two arrays.

my @a = qw\"abc def efg ghy klm ghn\";
m         


        
相关标签:
12条回答
  • 2020-12-06 19:06

    List::Compare

    if ( scalar List::Compare->new(\@a, \@b)->get_intersection ) {
        …
    }
    
    0 讨论(0)
  • 2020-12-06 19:09

    First of all, your 2 arrays need to be written correctly.

    @a = ("abc","def","efg","ghy","klm","ghn");
    @b = ("def","efg","ghy","klm","ghn","klm");
    

    Second of all, for arbitrary arrays (e.g. arrays whose elements may be references to other data structures) you can use Data::Compare.

    For arrays whose elements are scalar, you can do comparison using List::MoreUtils pairwise BLOCK ARRAY1 ARRAY2, where BLOCK is your comparison subroutine. You can emulate pairwise (if you don't have List::MoreUtils access) via:

    if (@a != @b) {
        $equals = 0;
    } else {
        $equals = 1;
        foreach (my $i = 0; $i < @a; $i++) {
            # Ideally, check for undef/value comparison here as well 
            if ($a[$i] != $b[$i]) { # use "ne" if elements are strings, not numbers
                                    # Or you can use generic sub comparing 2 values
                $equals = 0;
                last;
            }
        }
    }
    

    P.S. I am not sure but List::Compare may always sort the lists. I'm not sure if it can do pairwise comparisons.

    0 讨论(0)
  • 2020-12-06 19:10

    Check to create an intersect function, which will return a list of items that are present in both lists. Then your return value is dependent on the number of items in the intersected list.

    You can easily find on the web the best implementation of intersect for Perl. I remember looking for it a few years ago.

    Here's what I found :

    
    my @array1 = (1, 2, 3);
    my @array2 = (2, 3, 4);
    my %original = ();
    my @isect = ();
    
    map { $original{$_} = 1 } @array1;
    @isect = grep { $original{$_} } @array2;
    
    
    0 讨论(0)
  • 2020-12-06 19:11

    From the requirement that 'if any element matches', use the intersection of sets:

    sub set{
      my %set = map { $_, undef }, @_;
      return sort keys %set;
    }
    sub compare{
        my ($listA,$listB) = @_;
        return ( (set(@$listA)-set(@$listB)) > 0)
    }
    
    0 讨论(0)
  • 2020-12-06 19:14

    This is Perl. The 'obvious' solution:

    my @a = qw"abc def efg ghy klm ghn";
    my @b = qw"def ghy jgk lom com klm";
    print "arrays equal\n"
        if @a == @b and join("\0", @a) eq join("\0", @b);
    

    given "\0" not being in @a.

    But thanks for confirming that there is no other generic solution than rolling your own.

    0 讨论(0)
  • 2020-12-06 19:14
    my @a1 = qw|a b c d|;
    my @a2 = qw|b c d e|;
    
    for my $i (0..$#a1) {
        say "element $i of array 1 was not found in array 2" 
            unless grep {$_ eq $a1[$i]} @a2
    }
    
    0 讨论(0)
提交回复
热议问题