File Coverage

blib/lib/Array/Intersection.pm
Criterion Covered Total %
statement 20 20 100.0
branch 9 10 90.0
condition n/a
subroutine 4 4 100.0
pod 1 1 100.0
total 34 35 97.1


line stmt bran cond sub pod time code
1             package Array::Intersection;
2 1     1   89251 use strict;
  1         2  
  1         29  
3 1     1   4 use warnings;
  1         5  
  1         55  
4 1     1   665 use List::MoreUtils qw{uniq};
  1         12902  
  1         7  
5             require Exporter;
6             our @ISA = qw(Exporter);
7             our @EXPORT = qw(intersection);
8              
9             our $VERSION = '0.03';
10             our $UNDEF = "\000\001\002 QXJyYXk6OkludGVyc2VjdGlvbiBDb3B5cmlnaHQgKEMpIDIwMjQgYnkgTWljaGFlbCBSLiBEYXZpcw== \002\001\000"; #hash keys cannot be undef()
11              
12             =head1 NAME
13              
14             Array::Intersection - Calculates the intersection of two array references
15              
16             =head1 SYNOPSIS
17              
18             use Array::Intersection;
19             my @intersection = intersection([1,2,3,4], [3,4,5,6]); #expect (3,4)
20              
21             =head1 DESCRIPTION
22              
23             This package exports the intersection() function which uses the magic of a hash slice to return an intersection of the data.
24              
25             =head2 LIMITATIONS
26              
27             Hash keys are strings so numeric data like 1 and 1.0 will be uniqued away in the string folding process. However, the function folds undef into a unique string so that it supports both empty string "" and undef.
28              
29             =head2 FUNCTIONS
30              
31             =head2 intersection
32              
33             This intersection function uses a hash slice method to determine the intersection between the first array reference and the second array reference.
34              
35             my @intersection = intersection([1,2,3,4], [3,4,5,6]); #expect (3,4)
36             my @intersection = intersection(\@array_1, \@array_2);
37              
38             =cut
39              
40             sub intersection {
41 11     11 1 149175 my $syntax = 'Syntax: my @output = intersection(\@array1, \@array2)';
42 11 100       46 my $aref1 = shift or die($syntax);
43 10 50       21 my $aref2 = shift or die($syntax);
44 10 100       64 my %hash1 = map {defined ? ($_ => $_) : ($UNDEF => $UNDEF)} @$aref1; #fold undef into string, copy keys to values, and unique based on hash assignment
  10035         20036  
45 9 100       598 my @uniq2 = uniq map {defined ? $_ : $UNDEF } @$aref2; #fold undef into string, and uniq to perserve order of second array
  11028         20924  
46 8 100       7712 my @intersection = map {$_ eq $UNDEF ? undef : $_} grep {defined} @hash1{@uniq2}; #hash slice for values, remove undef values where not exists, revert undef keys from sting
  1014         1700  
  11027         11970  
47 8         7991 return @intersection;
48             }
49              
50             =head1 SEE ALSO
51              
52             https://perldoc.perl.org/perlfaq4#How-do-I-compute-the-difference-of-two-arrays?-How-do-I-compute-the-intersection-of-two-arrays?
53             L
54              
55             =head1 AUTHOR
56              
57             Michael R. Davis
58              
59             =head1 COPYRIGHT AND LICENSE
60              
61             Copyright (C) 2024 by Michael R. Davis
62              
63             MIT
64              
65             =cut
66              
67             1;