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

Hi, I have two arrays and I want to compare the contents to these two arrays. I installed Array::Compare and my code is as follows:

use Array::Compare;
my @arr1 = (1,2,3,4,5,6);
my @arr2 = (1,2,3,4,5,6);
my $comp = Array::Compare->new;
if ($comp->full_compare(\@arr1, \@arr2)) {
   print "Arrays are the same\n";
} else {
   print "Arrays are different\n";
}

I am using full_compare so that each and every element of the first array will be matched with the corresponding element of the second array. But, even through the two arrays have the same content, I encounter the message "Arrays are different". Can anyone tell me what would have went wrong in this? If I make a 'compare' or 'compare_len' the script is working perfectly.

Edit: Expanded title - davorg

Replies are listed 'Best First'.
Re: Array::Compare
by marto (Cardinal) on Jul 05, 2006 at 10:26 UTC
    Hi rsriram,

    Take a look at the if condition in my example below.
    #!/usr/bin/perl use strict; use warnings; use Array::Compare; my @arr1 = (1,2,3,4,5,6); my @arr2 = (1,2,3,4,5,6); my $comp = Array::Compare->new; if ($comp->full_compare(\@arr1, \@arr2) == 0) { print "Arrays are the same\n"; } else { print "Arrays are different\n"; }

    If in doubt check out the module documentation.

    Hope this helps

    Martin
Re: Array::Compare
by davorg (Chancellor) on Jul 05, 2006 at 10:29 UTC

    The return values from full_compare are confusing you here. From the documentation for full_compare:

    In scalar context returns the number of columns that differ (zero if the arrays are the same). In list context returns an list containing the indexes of the columns that differ (an empty list if the arrays are the same).

    So if the arrays are the same (which yours are) then full_compare returns an empty list (in list context) or zero (in scalar context). Your check is the wrong way round. You need:

    if ($comp->full_compare(\@arr1, \@arr2)) { print "Arrays are different\n"; } else { print "Arrays are the same.\n"; }

    And, yes, it's confusing. The return values for simple_compare are the other way round.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Array::Compare
by adrianh (Chancellor) on Jul 05, 2006 at 10:20 UTC
    I am using full_compare so that each and every element of the first array will be matched with the corresponding element of the second arra

    That's not the difference between compare() and full_compare(). According to the docs

    (the full comparison function) returns a list containing the indexes of elements which differ between the two arrays. If the arrays are the same it returns an empty list. In scalar context the full comparison returns the length of this list (i.e. the number of elements that dif- fer).

    Since the arrays are identical, the length of the list of differences is zero, which is what gets returned in a scalar context.

Re: Array::Compare
by GrandFather (Saint) on Jul 05, 2006 at 10:25 UTC

    full_compare in scalar context returns the number of different elements between the two lists. In this case there are no different elements so the result is 0 and the sense of the test is wrong.


    DWIM is Perl's answer to Gödel
Re: Using Array::Compare
by kabeldag (Hermit) on Jul 05, 2006 at 12:53 UTC
    Do you need to use a module to compare a list ?

    use strict; my @arrayone = ('a','b','c','d'); my @arraytwo = ('c','d','a','b'); my $arrays_match_result=match_arrays(\@arrayone,\@arraytwo); if($arrays_match_result==1) { print "Array's contain the same element value's.\n"; }else{ print "Array's do not contain the same element value's.\n"; } sub match_arrays { my ($array1,$array2)=@_; my @array1_matches; my @array2_matches; my $matches=0; # Return 0 straight away, if respective array lengths are not equa +l unless ($#$array1==$#$array2) { return 0; } for(my $mc1=0;$mc1<=$#$array1;$mc1++) { for(my $mc2=0;$mc2<=$#$array2;$mc2++) { # If the elements match. Eliminate the respective matched +elements (cross out the box's with the same contents) # and don't worry about them again. if(@$array1[$mc1] eq @$array2[$mc2]&&$array2_matches[$mc2] +!=1&&$array1_matches[$mc1]!=1) { $array2_matches[$mc2]=1; $array1_matches[$mc1]=1; $matches++; print "Match[$matches] -> Array1 : Element: $mc1 (@$ar +ray1[$mc1]) matched Array2 : Element: $mc2 (@$array2[$mc2])\n"; } } } if($matches==$#$array1+1) { return 1; }else{ return 0; } }

      Well no. Of course you don't need a module to do it. You don't need a module to do anything in Perl. But if you want to reuse the code in a number of programs then it makes sense to put it a module. Which is what I did. And then I put it on CPAN in the hope that it would save people time as they wouldn't need to write those functions themselves.

      But, obviously, feel free to not use it :-)

      --
      <http://dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg

        Hey.

        It's a great thing having bundled code. Don't get me wrong. I think it is good that you have created the module and I acknowlege the fact that you have. I was merely just posting a bit of code :).

        Just take off some of my XP ;') Good work on the module though.