in reply to Re: comparing two arrays
in thread comparing two arrays

Thank you very much for your input, it has helped me to understand the methodology. I am quite new at this and can't seem to leave it alone unless I understand it. My question, if I may be a little more specific, I am dealing with a situation where I need to action something if for example a file with following contents; sqltable table loaded successfully with 282873 records. mike_test table loaded successfully with 282873 records. sarak_mike table loaded successfully with 282873 records. compares to a hard coded array @report=("sqltable", "mike_test ", "sarak_mike"); I need to check an array containing the file input @file to see whether @file contains at least all the contents of @report. Your help is greatly appreciated.

Replies are listed 'Best First'.
(jeffa) 2Re: comparing two arrays
by jeffa (Bishop) on Nov 24, 2001 at 21:10 UTC
    No one has mentioned the Cookbook yet, so i will.

    If you need @file to contain at least all the elements of @report, then you need to find the simple difference of the two. The simple difference is the (paraphrasing from the Cookbook) "set of members of @report, but not of @file". If this set is empty, then @file contains at least all the elements of @report. So, working with Recipe 4.7:

    use strict; my @report = qw(sqltable mike_test sarak_mike); my @file = (@report, qw(plus a little more)); # off by 0 print '@file was off by ' . simple_compare(\@report,\@file) . " elements\n"; # still 0, that elem wasn't in @report pop @file; print '@file was off by ' . simple_compare(\@report,\@file) . " elements\n"; # off by 1, that one was shift @file; print '@file was off by ' . simple_compare(\@report,\@file) . " elements\n"; # returns number of elements in A that aren't in B sub simple_compare { my ($A,$B) = @_; # build lookup table my %seen = map { $_ => 1 } @$B; # find those in A that aren't in B my @aonly; foreach my $item (@$A) { push @aonly,$item unless ($seen{$item}); } return scalar @aonly; }
    (Array::Compare has a simple_compare() method, but it's definition of a simple compare is not the same as the Cookbook's.)

    Also note that this could only a be partial solution. What if you needed to compare these two arrays:

    my @report = qw(one one two); my @file = qw(one two two);
    Now what? @file definitely contains at least one of each element from @report. But, @file doesn't contain 2 'one's like @report does. If you need something like this, but you don't care about order, then use rob_au's suggestion and sort the arrays first. If you do care about order, use that code verbatim. Hope this helps!

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    F--F--F--F--F--F--F--F--
    (the triplet paradiddle)
    
      Thanks for your help. I'm so close, but something is not working. I am trying to debug the following, but it seems that although both the @file contain the @report strings, I am not getting a match. Is it possible when I load the text file into @file array, that the elements are not compared as strings? Frusterating!!!!! The contents of the @file looks like this:
      sqltable_mike table loaded successfully with 282873
      sarak_mike table loaded successfully with 282873 records
      sticks table loaded successfully with 282873 records.
      hello table loaded successfully with 282873 records.
      All I need it to do is match all @report contents with the internal @file. What am I doing wrong. Your assistance is greatly appreciated. <CODE> use strict;
      my @compare=();
      my $file='d:\mms_tableload.txt';
      my @file="";
      open(FILE,"<$file");
      @file = <FILE>;
      close(FILE);
      my @report = qw(sqltable_mike sarak_mike );
      my @compare = ( @report, qw (@file ));
      # off by 0
      print '@file was off by '
      . simple_compare(\@report,\@compare)
      . " elements\n";
      # still 0, that elem wasn't in @report
      pop @file;
      print '@file was off by '
      . simple_compare(\@report,\@compare)
      . " elements\n";
      # off by 1, that one was
      shift @file;
      print '@file was off by '
      . simple_compare(\@report,\@file)
      . " elements\n";
      # returns number of elements in A that aren't in B
      sub simple_compare {
      my ($A,$B) = @_;
      # build lookup table
      my %seen = map { $_ => 1 } @$B;
      # find those in A that aren't in B
      my @aonly;
      foreach my $item (@$A) {
      push @aonly,$item unless ($seen{$item});
      }
      return scalar @aonly;
      }
      <CODE>
        This is a problem:
        @file = ; # you probably meant @file = <FILE>; # and then you need to chomp @file; # to remove trailing new lines

        jeffa