Finding Elements in One Array but Not Another
Problem
You want to find elements that are in one array but not another.
Solution
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.
Straightforward implementation
# 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);
}
}More idiomatic version
my %seen; # lookup table
my @aonly; # answer
# build lookup table
@seen{@B} = ();
foreach $item (@A) {
push(@aonly, $item) unless exists $seen{$item};
}Discussion
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 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access