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

Hi, I need to compare the elements in two arrays and generate a new array consiting of 0 = match ,1 = no match eg
@a=(1,2,4,5,3) @b=(1,2,4,2,3) @c=(1,1,1,0,1)
I can do this in a very ugly way to make @c by using loops and indexes, is there a clean way to do this?

Replies are listed 'Best First'.
Re: compare two arrays
by jwkrahn (Abbot) on Dec 15, 2008 at 04:42 UTC
    $ perl -le' use List::MoreUtils q=pairwise=; # corrected, see comment below my @a = ( 1, 2, 4, 5, 3 ); my @b = ( 1, 2, 4, 2, 3 ); my @c = pairwise { $a == $b ? 1 : 0 } @a, @b; print "@c"; ' 1 1 1 0 1

      Typo: MList::MoreUtils should probably be List::MoreUtils (perhaps you were using the -M switch?)

        Yes I was, thanks for the correction.

Re: compare two arrays
by ccn (Vicar) on Dec 15, 2008 at 05:14 UTC
    my @c = map { $a[$_] == $b[$_] ? 1 : 0 } 0 .. $#a;
Re: compare two arrays
by matrixmadhan (Beadle) on Dec 15, 2008 at 05:31 UTC
    List::Compare is a CPAN module you should take a look at that.
      For completeness there's also Array::Compare, but using List::MoreUtils::pairwise or map will probably prove to be much faster.
Re: compare two arrays
by nagalenoj (Friar) on Dec 15, 2008 at 09:28 UTC
    Dear monk,

    We can also do like the below,

    my @a=(1,2,4,5,3); my @b=(1,2,4,2,3); my @c = map { $a[$_] <=> $b[$_] ? 0 : 1 } 0 .. $#a; print @c;
Re: compare two arrays
by moritz (Cardinal) on Dec 15, 2008 at 09:35 UTC
    If you can be sure that a certain character (or a sequence of characters) doesn't appear anywhere in your arrays, you can use join and string comparison:
    my $sep = chr(0); if (join($sep, @a) eq join($sep, @b)) { ... }

    TIMTOWTDI.

Re: compare two arrays
by johngg (Canon) on Dec 15, 2008 at 10:50 UTC

    TIMTOWTDI again.

    use strict; use warnings; my @arr1 = ( 1, 2, 4, 5, 3 ); my @arr2 = ( 1, 2, 4, 2, 3 ); my @diff = map m{\0} ? 1 : 0, split m{}, join( q{}, @arr1 ) ^ join( q{}, @arr2 ); print qq{@arr1\n@arr2\n@diff\n};

    The output.

    1 2 4 5 3 1 2 4 2 3 1 1 1 0 1

    Cheers,

    JohnGG

    Update: As pointed out by jwkrahn, this is a stupid solution that only works because all elements are one character. Please ignore or downvote. I'll get my coat.

      $ perl -e' my @arr1 = ( 1, 24, 5, 3 ); my @arr2 = ( 1, 2, 42, 3 ); my @diff = map /\0/ ? 1 : 0, split //, join( "", @arr1 ) ^ join( "", @ +arr2 ); print "@arr1\n@arr2\n@diff\n"; ' 1 24 5 3 1 2 42 3 1 1 1 0 1
       :-(

        Oh dear, not very robust then :-(

        Those weren't vitamin pills, they were stupid pills :-/