http://qs1969.pair.com?node_id=199207

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

Hey Monks
For some reason I am unable to wrap my head around this problem today. What I need to do is locate all elements in array 1 that are not in array2.
@array1 = ("q", "w", "e", "r", "t", "z"); @array2 = ("q", "w", "e", "r", "t", "y"); OUTPUT: ------- Value z does not match any value in @array2

My Effort

my $array1_size = scalar(@array1); my $array2_size = scalar(@array2); for(my $i = $array1_size; $i > 0 ; $i--) { for (my $j = $array2_size; $j > 0 ; $j--) { if ($array1[$i] eq $array2[$j]){ pop @array1; pop @array2; $j--; $i--; $array1_size--; $array2_size--; } } }
Thanks to all in advance.

Ever have one of those days?
j o h n i r l .

 Sum day soon I'Il lern how 2 spelI (nad tYpe)

Replies are listed 'Best First'.
Re: Comparing Two arrays
by davorg (Chancellor) on Sep 19, 2002 at 16:05 UTC

    Perhaps you'll allow me a little plug for Array::Compare.

    #!/usr/bin/perl -w use strict; use Array::Compare; my $cmp = Array::Compare->new; my @array1 = ("q", "w", "e", "r", "t", "z"); my @array2 = ("q", "w", "e", "r", "t", "y"); my @diffs = $cmp->full_compare(\@array1, \@array2); if (@diffs) { print "No matches for @array1[@diffs]\n"; } else { print "Arrays match\n"; }
    --
    <http://www.dave.org.uk>

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

Re: Comparing Two arrays
by Zaxo (Archbishop) on Sep 19, 2002 at 15:56 UTC

    This is a faq, but here goes:

    my @array1 = ("q", "w", "e", "r", "t", "z"); my @array2 = ("q", "w", "e", "r", "t", "y"); my %hash; @hash{@array2} = () x @array2; my @not_there = grep { ! exists $hash($_} } @array1;
    exists is used to prevent autovivication of new keys from @array1 in %hash.

    Update: This method's run time is O(NlogN) or therabouts, while your attempt is O(N**2). ++fruiture for spotting a thinko, corrected.

    After Compline,
    Zaxo

      This method's run time is O(NlogN) or therabouts, while your attempt is O(N**2).

      I think your method is actually O(N+M) as you iterate each array once and johnirl's is O(N*M) because he iterates one array for each element in the other.

      The difference in array size might be significant. That is why I used two different variables: N and M.

      Update: A short /msg exchange with Zaxo prompted me to point out that searches and updates on hashes are expected to be O(1). That is, assuming that the hash function is a good one for your data. I believe it is a reasonable assumption to make here.

      -sauoq
      "My two cents aren't worth a dime.";
      
Re: Comparing Two arrays
by fruiture (Curate) on Sep 19, 2002 at 15:57 UTC

    Try using Perl, not C ;-)

    my @array1 = qw/a b c d e f/; my @array2 = qw/ b c d /; # you see: result must be a, e and f my @in1notin2 = do { my %tmp = map {($_=>undef)} @array2; grep not exists $tmp{$_}, @array1 }; print "The elements @in1notin2 can be found in array 1, but not in arr +ay 2\n";
    --
    http://fruiture.de
•Re: Comparing Two arrays
by merlyn (Sage) on Sep 19, 2002 at 15:57 UTC
    Ahh. It's september, and the lovely smell of "new homework assignments" are in the air.

    On the odds that you're not a student looking for a quick fix (because you've given no hints to the contrary, unfortunately), I'd suggest one word: "FAQ".

    -- Randal L. Schwartz, Perl hacker

      Hey Merlyn,
      you're dead right I am a student but this isn't a college deadline. I'm finishing my work experience in a week and I am seriously running out of time to finish my work. I realise that the answer is a realativly simple one it's just that time is of the essence and I rather spend the time I have on more complex than trying to figure it out when there are gracious and knowledgable monks as yourself out there for the asking.

      j o h n i r l .

       Sum day soon I'Il lern how 2 spelI (nad tYpe)

Re: Comparing Two arrays
by RollyGuy (Chaplain) on Sep 19, 2002 at 16:00 UTC
    I have a method here that should work for you. The first thing we'll do is create a subroutine that checks for existance of an item in an array. Then we'll loop over every element in Array1 and check for it's existance in Array2. The code looks like:

    sub in_array{ my $value = shift; my @array = @_; foreach $item (@array){ if($value eq $item){ return 1; } } return 0; } @array1 = ("q", "w", "e", "r", "t","z"); @array2 = ("q", "w", "e", "r", "t","y"); foreach $value (@array1){ if(!in_array($value,@array2)){ print "Value $value does not match any value in \@array2\n"; } }


    This should output exactly what you want. Enjoy.
Re: Comparing Two arrays
by nandeya (Monk) on Sep 19, 2002 at 18:45 UTC
Re: Comparing Two arrays
by Joost (Canon) on Sep 20, 2002 at 10:57 UTC
    Set::Scalar should be able to do the job.
    -- Joost downtime n. The period during which a system is error-free and immune from user input.