You want to find elements in @A
that aren’t
in @B
. Build a hash of the keys of
@B
to use as a lookup table. Then check each
element in @A
to see if it is in
@B
.
# assume @A and @B are already loaded %seen = (); # lookup table to test membership of B @aonly = (); # answer # build lookup table foreach $item (@B) { $seen{$item} = 1 } # find only elements in @A and not in @B foreach $item (@A) { unless ($seen{$item}) { # it's not in %seen, so add to @aonly push(@aonly, $item); } }
As
with nearly any problem in Perl that asks whether a scalar is in one
list or another, this one uses a hash. First, process
@B
so that the %seen
hash
records each element from @B
by setting its value
to 1. Then process @A
one element at a time,
checking whether that particular element had been in
@B
by consulting the %seen
hash.
The given code retains duplicate elements in @A
.
This can be easily fixed by adding the elements of
@A
to %seen
as they are
processed:
foreach $item (@A) { push(@aonly, $item) unless $seen{$item}; $seen{$item} = 1; # mark as seen }
The two solutions differ mainly in how they build the hash. The first
iterates through @B
. The second uses a
hash slice to initialize the hash. A
hash slice is easiest illustrated by
example:
$hash{"key1"} = 1; $hash{"key2"} = 2;
is equivalent to:
@hash{"key1", "key2"} = (1,2);
The list in the curly braces holds the keys; the list on the right
holds the values. We initialize %seen
in the first
solution by looping over each element in @B
and
setting the appropriate value of %seen
to 1. In
the second, we simply say:
@seen{@B} = ();
This uses items in @B
as keys for
%seen
, setting each corresponding value to
undef
, because there are fewer values on the right
than places to put them. This works out here because we check for
existence of the key, not logical truth or
defined
ness of the value. If we needed true
values, a slice could still shorten our code:
@seen{@B} = (1) x @B;
Hash slices are explained in perldata
(1) and
the “Variables” section of Chapter 2 of
Programming Perl; Chapter 5; we use hashes in a similar fashion in Section 4.6 and Section 4.8
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.