如何检查两个数组在Perl中是否包含相同的元素?

use*_*341 7 arrays perl

所以我需要的是一个简单的方法来判断两个数组在perl中是否相同.订单没关系,所以我正在寻找这样的东西:

my @a = (1, 2, 3);

my @b = (2, 3, 1);

my @c = (1, 2, 4);

&identical(@a, @b) 返回1

&identical(@a, @c) 返回0

谢谢!

cHa*_*Hao 6

你可以在哈希中计算元素的计数.有一个(element => count)哈希值,每次第一个数组有该元素时都会向上计数,每次有另一个数据时就向下计数(反之亦然).如果两个数组具有所有相同的元素,则散列中的每个值都将为0.

sub have_same_elements {
    my ($arr1, $arr2) = @_;
    my %counts = ();
    $counts{$_} += 1 foreach (@$arr1);
    $counts{$_} -= 1 foreach (@$arr2);
    return !(grep { $_ != 0 } values %counts);
}


$a_and_b_same = have_same_elements(\@a, \@b);  # will be true
$a_and_c_same = have_same_elements(\@a, \@c);  # will be false
Run Code Online (Sandbox Code Playgroud)

(注意,这可能会或者可能不适用于执行自己的字符串化的对象.散列键不能是引用,因此Perl会在您使用它们时对引用进行字符串化.它的默认字符串将引用转换为类似的内容ARRAY(0x12345678),这使得引用不同,除非它们'但是如果一个对象做了自己的字符串化并且没有为不同的引用返回不同的字符串,那么这可能会破坏.只是你知道.)


小智 5

如果你正在使用Perl 5.10或更大(如果你不是,你真的应该升级),你可以使用智能匹配运算符:

use strict;
use warnings;

my @a = (1, 2, 3);
my @b = (2, 3, 1);
my @c = (1, 2, 4);

#sort each of them (numerically)
@a = sort { $a <=> $b } @a;
@b = sort { $a <=> $b } @b;
@c = sort { $a <=> $b } @c;

if ( @a ~~ @b ) {

    print "\@a and \@b are the same! (after sorting)\n";
}
else {

    print "nope\n";
}

if ( @a ~~ @c ) {

    print "\@a and \@c are the same! (after sorting)\n";
}
else {

    print "nope\n";
}
Run Code Online (Sandbox Code Playgroud)

你也可以推出自己的功能:

use strict;
use warnings;

my @a = (1, 2, 3);
my @b = (2, 3, 1);
my @c = (1, 2, 4);

print same_elements(\@a, \@b) . "\n";
print same_elements(\@a, \@c) . "\n";

#arguments are two array references
sub same_elements {

    my $array_ref_1 = shift;
    my $array_ref_2 = shift;
    my @arr1 = @$array_ref_1;
    my @arr2 = @$array_ref_2;

    #If they are not the same length, we are done.
    if( scalar(@arr1) != scalar(@arr2) ) {

       return 0;
    }

    #sort them!
    @arr1 = sort { $a <=> $b } @arr1;
    @arr2 = sort { $a <=> $b } @arr2;

    foreach my $i( 0 .. $#arr1 ) {

        if ( $arr1[$i] != $arr2[$i] ) {
            return 0;
        }
    }
    return 1;
}
Run Code Online (Sandbox Code Playgroud)