noviceuser has asked for the wisdom of the Perl Monks concerning the following question:

i have to compare two arrays to check if both are exactly same or not irrespective of which elements come at which position

here @failedTestsuites is first array and @referenceTestsuites is second array, i have tried below code but it is not giving desired result. one of the case is: suppose @failedTestsuites array contains 'a','b','c' and @referenceTestsuites array contains 'a','b' then also it is printing both array as same. please help

my $comp = Array::Compare->new; if ($comp->compare(\@failedTestsuites, \@referenceTestsuites)) { print "same arrays\n"; } else { print "different arrays\n"; }
  • Comment on compare two arrays if both are equal and have same elements irrespective of their position
  • Download Code

Replies are listed 'Best First'.
Re: compare two arrays if both are equal and have same elements irrespective of their position
by davido (Cardinal) on Jun 16, 2021 at 17:45 UTC

    You should read the documentation for Array::Compare. It's useful. It's written to answer these sorts of questions. I think you simply want to change $comp->compare to $comp->perm. This is in the module's POD. Here's a test example:

    #!/usr/bin/env perl use strict; use warnings; use List::Util qw(shuffle); use Array::Compare; my @array1 = shuffle(1..100); my @array2 = shuffle(@array1); my $comp = Array::Compare->new; print "perm: ", $comp->perm(\@array1, \@array2) ? "Same elements\n" : "Different elements\n"; print "compare: ", $comp->compare(\@array1, \@array2) ? "Same elements, same order\ +n" : "Different elements or diff +erent order\n";

    The shuffle gives a 1:100! chance of the lists being in the same order, I think. So for this test we can usually assume that the elements start out in dissimilar orders. But we do test for that just to be sure. If we run it the output should be:

    perm: Same elements compare: Different elements or different order

    So even though the elements come in a different order, the perm() method determines that we got the same elements.


    Dave

      thanks a lot, changing to $comp->perm worked.
Re: compare two arrays if both are equal and have same elements irrespective of their position
by choroba (Archbishop) on Jun 16, 2021 at 18:00 UTC
    You can use Test::Deep::NoTest to import functions from Test::Deep without interacting with tests.

    #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; use List::Util qw(shuffle); use Test::Deep::NoTest qw{ eq_deeply bag }; my @array1 = shuffle(1..100); my @array2 = shuffle(@array1); say eq_deeply(\@array1, bag(@array2)); # 1
    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      Do you know a way to create a bag using Test2::V0 as easy as in your example? I've been searching for something like that without luck.

      Greetings,
      -jo

      $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
        You can write a simple helper sub yourself (or maybe write many of them and upload them to CPAN):
        use Test2::V0; sub mybag { my @ar = @_; bag { item $_ for @ar ; end } } is(\@array1, mybag(@array2));
        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: compare two arrays if both are equal and have same elements irrespective of their position
by jo37 (Hermit) on Jun 16, 2021 at 18:35 UTC

    There are plenty of features in Test2::V0. To compare an array with an unordered list of its values, there are bags. You may do something like:

    use Test2::V0; my $have = [qw(c a b)]; is $have, bag {item $_ for qw(a b c); end}, 'matches'; isnt $have, bag {item $_ for qw(a a b c); end}, 'missing dup'; isnt $have, bag {item $_ for qw(a b); end}, 'one to much'; isnt $have, bag {item $_ for qw(a b c d); end}, 'one missing';

    Greetings,
    -jo

    $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
Re: compare two arrays if both are equal and have same elements irrespective of their position
by kcott (Bishop) on Jun 18, 2021 at 06:05 UTC

    G'day noviceuser,

    Based on the simplicity of your example arrays, and your subsequent "No, i have just started out perl sometimes back. Any regular way will work", you might be interested in this basic solution that doesn't employ modules.

    #!/usr/bin/env perl use strict; use warnings; my @data = ( [[qw{a b}], [qw{a b}]], [[qw{a b}], [qw{a}]], [[qw{a b}], [qw{a b c}]], [[qw{a b}], [qw{b 99 xyz}]], ); for (@data) { my @ref = @{$_->[0]}; my @test = @{$_->[1]}; print "REF: '@ref' TEST: '@test'\n"; my ($only_in_ref, $not_in_ref) = compare(\@ref, \@test); print "Only in REF: @{[sort keys %$only_in_ref]}\n"; print "Not in REF: @{[sort keys %$not_in_ref]}\n"; print '-' x 40, "\n"; } sub compare { my ($ref, $test) = @_; my %only_in_ref = map +($_ => 1), @$ref; my %not_in_ref; for (@$test) { if (exists $only_in_ref{$_}) { delete $only_in_ref{$_}; } else { ++$not_in_ref{$_}; } } return (\%only_in_ref, \%not_in_ref); }

    Output:

    REF: 'a b' TEST: 'a b' Only in REF: Not in REF: ---------------------------------------- REF: 'a b' TEST: 'a' Only in REF: b Not in REF: ---------------------------------------- REF: 'a b' TEST: 'a b c' Only in REF: Not in REF: c ---------------------------------------- REF: 'a b' TEST: 'b 99 xyz' Only in REF: a Not in REF: 99 xyz ----------------------------------------

    — Ken

Re: compare two arrays if both are equal and have same elements irrespective of their position
by LanX (Cardinal) on Jun 16, 2021 at 17:33 UTC
    EDIT: I only noticed after reading the code that the question is especially about Array::Compare , so my answer may only be tangential.


    do you know Test::More ? especially the function is_deeply ?

    is_deeply($got_complex_structure, $expected_complex_structure, $test_name);

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      No, i have just started out perl sometimes back. Any regular way will work