In Chapter 4, Section 4.8 (Computing Union, Intersection, or Difference of Unique Lists), the Perl Cookbook provides this technique for getting the intersection of two lists
@a = qw(a B c d);
@b = qw(b c D e f);
@c = grep { $f = lc $_; grep lc $_ eq $f, @b } @a;
gives
B c d
1) I found this solution somewhere but I don't remember where. If somebody knows please let me know.
2) I have no idea how efficient this is compared to other solutions.
3) Sincerly, I do not know how this works. Why there is a semicolon and not a comma?
Array::Utils is what you're looking for.
use Array::Utils qw(:all);
my @a = qw( a b c d );
my @b = qw( c d e f );
my @isect = intersect(@a, @b);
print join(",",@isect) . "\n";
This produces the expected output of
c,d
Edit: I didn't notice that you wanted this done case-insensitively. In that case, you can replace @a
with map{lc}@a
(and likewise with @b
).
Smallest amount of change required from the original solution. Just lower-case the strings.
@a = qw( a b c d );
@b = qw( C D E F );
...
foreach $e (@a, @b) {
$union{lc $e}++ && $isect{lc $e}++
}
@union = keys %union;
@isect = keys %isect;
Here's one map
/grep
approach:
my @a = qw(Perl PHP Ruby Python C JavaScript);
my @b = qw(erlang java perl python c snobol lisp);
my @intersection =
grep { defined }
@{ { map { lc ,=> $_ } @a } }
{ map { lc } @b };
# @intersection = qw(Perl Python C)