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)
|