1List::Compare::FunctionUasle(r3)Contributed Perl DocumenLtiastti:o:nCompare::Functional(3)
2
3
4

NAME

6       List::Compare::Functional - Compare elements of two or more lists
7

VERSION

9       This document refers to version 0.55 of List::Compare::Functional.
10       This version was released August 16 2020.  The first released version
11       of List::Compare::Functional was v0.21.  Its version numbers are set to
12       be consistent with the other parts of the List::Compare distribution.
13
14   Notice of Interface Changes
15       Certain significant changes to the interface to
16       List::Compare::Functional were made with the introduction of Version
17       0.25 in April 2004.  The documentation immediately below reflects those
18       changes, so if you are first using this module with that or a later
19       version, simply read and follow the documentation below.  If, however,
20       you used List::Compare::Functional prior to that version, see the
21       discussion of interface changes farther below: April 2004 Change of
22       Interface.
23

SYNOPSIS

25   Getting Started
26       List::Compare::Functional exports no subroutines by default.
27
28           use List::Compare::Functional qw(:originals :aliases);
29
30       will import all publicly available subroutines from
31       List::Compare::Functional.  The model for importing just one subroutine
32       from List::Compare::Functional is:
33
34           use List::Compare::Functional qw( get_intersection );
35
36       It will probably be most convenient for the user to import functions by
37       using one of the two following export tags:
38
39           use List::Compare::Functional qw(:main :mainrefs);
40
41       The assignment of the various comparison functions to export tags is
42       discussed below.
43
44       For clarity, we shall begin by discussing comparisons of just two lists
45       at a time.  Farther below, we shall discuss comparisons among three or
46       more lists at a time.
47
48   Comparing Two Lists Held in Arrays
49       ·   Given two lists:
50
51               @Llist = qw(abel abel baker camera delta edward fargo golfer);
52               @Rlist = qw(baker camera delta delta edward fargo golfer hilton);
53
54       ·   Get those items which appear at least once in both lists (their
55           intersection).
56
57               @intersection = get_intersection( [ \@Llist, \@Rlist ] );
58
59           Note that you could place the references to the lists being
60           compared into a named array and then pass "get_intersection()" a
61           reference to that array.
62
63               @to_be_compared = ( \@Llist, \@Rlist );
64               @intersection = get_intersection( \@to_be_compared );
65
66           Beginning with version 0.29 (May 2004), List::Compare::Functional
67           now offers an additional way of passing arguments to its various
68           functions.  If you prefer to see a more explicit delineation among
69           the types of arguments passed to a function, pass a single hash
70           reference which holds the lists being compared in an anonymous
71           array which is the value corresponding to key "lists":
72
73               @intersection = get_intersection( {
74                  lists => [ \@Llist, \@Rlist ],
75               } );
76
77       ·   Get those items which appear at least once in either list (their
78           union).
79
80               @union = get_union( [ \@Llist, \@Rlist ] );
81
82           or
83
84               @union = get_union( { lists => [ \@Llist, \@Rlist ] } );
85
86       ·   Get those items which appear (at least once) only in the first
87           list.
88
89               @Lonly = get_unique( [ \@Llist, \@Rlist ] );
90
91           or
92
93               @Lonly = get_unique( { lists => [ \@Llist, \@Rlist ] } );
94
95       ·   Get those items which appear (at least once) only in the second
96           list.
97
98               @Ronly = get_complement( [ \@Llist, \@Rlist ] );
99
100           or
101
102               @Ronly = get_complement( { lists => [ \@Llist, \@Rlist ] } );
103
104       ·
105
106
107               @LorRonly = get_symmetric_difference( [ \@Llist, \@Rlist ] );
108
109               @LorRonly = get_symdiff( [ \@Llist, \@Rlist ] );       # alias
110
111           or
112
113               @LorRonly = get_symmetric_difference( { lists => [ \@Llist, \@Rlist ] } );
114
115       ·   Make a bag of all those items in both lists.  The bag differs from
116           the union of the two lists in that it holds as many copies of
117           individual elements as appear in the original lists.
118
119               @bag = get_bag( [ \@Llist, \@Rlist ] );
120
121           or
122
123               @bag = get_bag( { lists => [ \@Llist, \@Rlist ] } );
124
125       ·   An alternative approach to the above functions:  If you do not
126           immediately require an array as the return value of the function
127           call, but simply need a reference to an (anonymous) array, use one
128           of the following parallel functions:
129
130               $intersection_ref = get_intersection_ref(         [ \@Llist, \@Rlist ] );
131               $union_ref        = get_union_ref(                [ \@Llist, \@Rlist ] );
132               $Lonly_ref        = get_unique_ref(               [ \@Llist, \@Rlist ] );
133               $Ronly_ref        = get_complement_ref(           [ \@Llist, \@Rlist ] );
134               $LorRonly_ref     = get_symmetric_difference_ref( [ \@Llist, \@Rlist ] );
135               $LorRonly_ref     = get_symdiff_ref(              [ \@Llist, \@Rlist ] );
136                                       # alias
137               $bag_ref          = get_bag_ref(                  [ \@Llist, \@Rlist ] );
138
139           or
140
141               $intersection_ref =
142                   get_intersection_ref(         { lists => [ \@Llist, \@Rlist ] } );
143               $union_ref        =
144                   get_union_ref(                { lists => [ \@Llist, \@Rlist ] } );
145               $Lonly_ref        =
146                   get_unique_ref(               { lists => [ \@Llist, \@Rlist ] } );
147               $Ronly_ref        =
148                   get_complement_ref(           { lists => [ \@Llist, \@Rlist ] } );
149               $LorRonly_ref     =
150                   get_symmetric_difference_ref( { lists => [ \@Llist, \@Rlist ] } );
151               $LorRonly_ref     =
152                   get_symdiff_ref(              { lists => [ \@Llist, \@Rlist ] } );
153                   # alias
154               $bag_ref          =
155                   get_bag_ref(                  { lists => [ \@Llist, \@Rlist ] } );
156
157       ·   Return a true value if the first list ('L' for 'left') is a subset
158           of the second list ('R' for 'right').
159
160               $LR = is_LsubsetR( [ \@Llist, \@Rlist ] );
161
162           or
163
164               $LR = is_LsubsetR( { lists => [ \@Llist, \@Rlist ] } );
165
166       ·   Return a true value if R is a subset of L.
167
168               $RL = is_RsubsetL( [ \@Llist, \@Rlist ] );
169
170           or
171
172               $RL = is_RsubsetL( { lists => [ \@Llist, \@Rlist ] } );
173
174       ·   Return a true value if L and R are equivalent, i.e., if every
175           element in L appears at least once in R and vice versa.
176
177               $eqv = is_LequivalentR( [ \@Llist, \@Rlist ] );
178               $eqv = is_LeqvlntR( [ \@Llist, \@Rlist ] );            # alias
179
180           or
181
182               $eqv = is_LequivalentR( { lists => [ \@Llist, \@Rlist ] } );
183
184       ·   Return a true value if L and R are disjoint, i.e., if L and R have
185           no common elements.
186
187               $disj = is_LdisjointR( [ \@Llist, \@Rlist ] );
188
189           or
190
191               $disj = is_LdisjointR( { lists => [ \@Llist, \@Rlist ] } );
192
193       ·   Pretty-print a chart showing whether one list is a subset of the
194           other.
195
196               print_subset_chart( [ \@Llist, \@Rlist ] );
197
198           or
199
200               print_subset_chart( { lists => [ \@Llist, \@Rlist ] } );
201
202       ·   Pretty-print a chart showing whether the two lists are equivalent
203           (same elements found at least once in both).
204
205               print_equivalence_chart( [ \@Llist, \@Rlist ] );
206
207           or
208
209               print_equivalence_chart( { lists => [ \@Llist, \@Rlist ] } );
210
211       ·   Determine in which (if any) of the lists a given string can be
212           found.  In list context, return a list of those indices in the
213           argument list corresponding to lists holding the string being
214           tested.
215
216               @memb_arr = is_member_which( [ \@Llist, \@Rlist ] , [ 'abel' ] );
217
218           or
219
220               @memb_arr = is_member_which( {
221                   lists => [ \@Llist, \@Rlist ],  # value is array reference
222                   item  => 'abel',                # value is string
223               } );
224
225           In the example above, @memb_arr will be:
226
227               ( 0 )
228
229           because 'abel' is found only in @Al which holds position 0 in the
230           list of arguments passed to "new()".
231
232       ·   As with other List::Compare::Functional functions which return a
233           list, you may wish the above function returned a (scalar) reference
234           to an array holding the list:
235
236               $memb_arr_ref = is_member_which_ref( [ \@Llist, \@Rlist ] , [ 'baker' ] );
237
238           or
239
240               $memb_arr_ref = is_member_which_ref( {
241                   lists => [ \@Llist, \@Rlist ],  # value is array reference
242                   item  => 'baker',               # value is string
243               } );
244
245           In the example above, $memb_arr_ref will be:
246
247               [ 0, 1 ]
248
249           because 'baker' is found in @Llist and @Rlist, which hold positions
250           0 and 1, respectively, in the list of arguments passed to "new()".
251
252           Note:  functions "is_member_which()" and "is_member_which_ref" test
253           only one string at a time and hence take only one argument.  To
254           test more than one string at a time see the next function,
255           "are_members_which()".
256
257       ·   Determine in "which" (if any) of the lists passed as arguments one
258           or more given strings can be found.  The lists beings searched are
259           placed in an array, a reference to which is the first argument
260           passed to "are_members_which()".  The strings to be tested are also
261           placed in an array, a reference to which is the second argument
262           passed to that function.
263
264               $memb_hash_ref =
265                   are_members_which( [ \@Llist, \@Rlist ] ,
266                                      [ qw| abel baker fargo hilton zebra | ]
267                                    );
268
269           or
270
271               $memb_hash_ref = are_members_which( {
272                   lists => [ \@Llist, \@Rlist ],                    # value is arrayref
273                   items => [ qw| abel baker fargo hilton zebra | ], # value is arrayref
274               } );
275
276           The return value is a reference to a hash of arrays.  The key for
277           each element in this hash is the string being tested.  Each
278           element's value is a reference to an anonymous array whose elements
279           are those indices in the constructor's argument list corresponding
280           to lists holding the strings being tested.  In the examples above,
281           $memb_hash_ref will be:
282
283               {
284                    abel     => [ 0    ],
285                    baker    => [ 0, 1 ],
286                    fargo    => [ 0, 1 ],
287                    hilton   => [    1 ],
288                    zebra    => [      ],
289               };
290
291           Note:  "are_members_which()" can take more than one argument;
292           "is_member_which()" and "is_member_which_ref()" each take only one
293           argument.  Unlike those functions, "are_members_which()" returns a
294           hash reference.
295
296       ·   Determine whether a given string can be found in any of the lists
297           passed as arguments.  Return 1 if a specified string can be found
298           in any of the lists and 0 if not.
299
300               $found = is_member_any( [ \@Llist, \@Rlist ] , [ 'abel' ] );
301
302           or
303
304               $found = is_member_any( {
305                   lists => [ \@Llist, \@Rlist ], # value is array reference
306                   item  => 'abel',               # value is string
307               } );
308
309           In the example above, $found will be 1 because 'abel' is found in
310           one or more of the lists passed as arguments to "new()".
311
312       ·   Determine whether a specified string or strings can be found in any
313           of the lists passed as arguments. The lists beings searched are
314           placed in an array, a reference to which is the first argument
315           passed to "are_members_any()".  The strings to be tested are also
316           placed in an array, a reference to which is the second argument
317           passed to that function.
318
319               $memb_hash_ref =
320                   are_members_any( [ \@Llist, \@Rlist ] ,
321                                    [ qw| abel baker fargo hilton zebra | ]
322                                  );
323
324           or
325
326               $memb_hash_ref = are_members_any( {
327                   lists => [ \@Llist, \@Rlist ],                    # value is arrayref
328                   items => [ qw| abel baker fargo hilton zebra | ], # value is arrayref
329               } );
330
331           The return value is a reference to a hash where an element's key is
332           the string being tested and the element's value is 1 if the string
333           can be found in any of the lists and 0 if not.  In the examples
334           above, $memb_hash_ref will be:
335
336               {
337                    abel     => 1,
338                    baker    => 1,
339                    fargo    => 1,
340                    hilton   => 1,
341                    zebra    => 0,
342               };
343
344           "zebra"'s value is 0 because "zebra" is not found in either of the
345           lists passed as arguments to "are_members_any()".
346
347       ·   Return current List::Compare::Functional version number.
348
349               $vers = get_version;
350
351   Comparing Three or More Lists Held in Arrays
352       Given five lists:
353
354           @Al     = qw(abel abel baker camera delta edward fargo golfer);
355           @Bob    = qw(baker camera delta delta edward fargo golfer hilton);
356           @Carmen = qw(fargo golfer hilton icon icon jerky kappa);
357           @Don    = qw(fargo icon jerky);
358           @Ed     = qw(fargo icon icon jerky);
359
360       ·   Get those items which appear at least once in each list (their
361           intersection).
362
363               @intersection = get_intersection( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
364
365           or
366
367               @intersection = get_intersection( {
368                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
369               } );
370
371       ·   Get those items which appear at least once in any of the lists
372           (their union).
373
374               @union = get_union( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
375
376           or
377               @union = get_union( {
378                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
379               } );
380
381       ·   To get those items which are unique to a particular list, provide
382           "get_unique()" with two array references.  The first holds
383           references to the arrays which in turn hold the individual lists
384           being compared.  The second holds the index position in the first
385           reference of the particular list under consideration.  Example:  To
386           get elements unique to @Carmen:
387
388               @Lonly = get_unique(
389                            [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
390                            [ 2 ]
391                        );
392
393           or
394
395               @Lonly = get_unique( {
396                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ], # value is arrayref
397                   item  => 2,                                      # value is number
398               } );
399
400           If no index position is passed to "get_unique()" it will default to
401           0 and report items unique to the first list passed to the function.
402           Hence,
403
404               @Lonly = get_unique( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
405
406           is same as:
407
408               @Lonly = get_unique( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ], [ 0 ] );
409
410       ·   Should you need to identify the items unique to each of the lists
411           under consideration, call "get_unique_all" and get a reference to
412           an array of array references:
413
414               $unique_all_ref = get_unique_all(
415                   [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ]
416               );
417
418           or
419
420               $unique_all_ref = get_unique_all( {
421                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
422               } );
423
424       ·   To get those items which appear only in lists other than one
425           particular list, pass two array references to the
426           "get_complement()"  function.  The first holds references to the
427           arrays which in turn hold the individual lists being compared.  The
428           second holds the index position in the first reference of the
429           particular list under consideration.  Example:  to get all the
430           elements found in lists other than @Don:
431
432               @Ronly = get_complement(
433                            [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
434                            [ 3 ]
435                        );
436
437           or
438
439               @Ronly = get_complement( {
440                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ], # value is arrayref
441                   item  => 3,                                      # value is number
442               } );
443
444           If no index position is passed to "get_complement()" it will
445           default to 0 and report items found in all lists other than the
446           first list passed to "get_complement()".
447
448               @Lonly = get_complement( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
449
450           is same as:
451
452               @Lonly = get_complement( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ], [ 0 ] );
453
454       ·   Should you need to identify the items not found in each of the
455           lists under consideration, call "get_complement_all" and get a
456           reference to an array of array references:
457
458               $complement_all_ref = get_complement_all(
459                   [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ]
460               );
461
462           or
463
464               $complement_all_ref = get_complement_all( {
465                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
466               } );
467
468       ·   Get those items which do not appear in more than one of several
469           lists (their symmetric_difference);
470
471               @LorRonly = get_symmetric_difference( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
472               @LorRonly = get_symdiff( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] ); # alias
473
474           or
475
476               @LorRonly = get_symmetric_difference( {
477                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
478               } );
479
480       ·   Get those items found in any of several lists which do not appear
481           in "all" of the lists (i.e., all items except those found in the
482           intersection of the lists):
483
484               @nonintersection = get_nonintersection(
485                                      [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
486
487           or
488
489               @nonintersection = get_nonintersection( {
490                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
491               } );
492
493       ·   Get those items which appear in more than one of several lists
494           (i.e., all items except those found in their symmetric difference);
495
496               @shared = get_shared( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
497
498           or
499
500               @shared = get_shared( {
501                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
502               } );
503
504       ·   Make a bag of every item found in every list.  The bag differs from
505           the union of the two lists in that it holds as many copies of
506           individual elements as appear in the original lists.
507
508               @bag = get_bag( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
509
510           or
511
512               @bag = get_bag( {
513                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
514               } );
515
516       ·   An alternative approach to the above functions:  If you do not
517           immediately require an array as the return value of the function,
518           but simply need a reference to an array, use one of the following
519           parallel functions:
520
521               $intersection_ref    = get_intersection_ref(
522                                        [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
523               $union_ref           = get_union_ref(
524                                        [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
525               $Lonly_ref           = get_unique_ref(
526                                        [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
527               $Ronly_ref           = get_complement_ref(
528                                        [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
529               $LorRonly_ref        = get_symmetric_difference_ref(
530                                        [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
531               $LorRonly_ref        = get_symdiff_ref(            # alias
532                                        [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
533               $nonintersection_ref = get_nonintersection_ref(
534                                        [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
535               $shared_ref          = get_shared_ref(
536                                        [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
537               $bag_ref             = get_bag_ref(
538                                        [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
539
540       ·   To determine whether one particular list is a subset of another of
541           the lists passed to the function, pass to "is_LsubsetR()" two array
542           references.  The first of these is a reference to an array of array
543           references, the arrays holding the lists under consideration.  The
544           second is a reference to a two-element array consisting of the
545           index of the presumed subset, followed by the index position of the
546           presumed superset.  A true value (1) is returned if the first
547           (left-hand) element in the second reference list is a subset of the
548           second (right-hand) element; a false value (0) is returned
549           otherwise.
550
551           Example:  To determine whether @Ed is a subset of @Carmen, call:
552
553               $LR = is_LsubsetR(
554                         [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
555                         [ 4, 2 ]
556                     );
557
558           or
559
560               $LR = is_LsubsetR( {
561                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ], # value is arrayref
562                   pair  => [ 4, 2 ],                               # value is arrayref
563               } );
564
565           If only the first reference (to the array of lists) is passed to
566           "is_LsubsetR", then the function's second argument defaults to
567           "(0,1)" and compares the first two lists passed to the constructor.
568           So,
569
570               $LR = is_LsubsetR([ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
571
572           ... is equivalent to:
573
574               $LR = is_LsubsetR([ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ], [0,1] );
575
576       ·   To reverse the order in which the particular lists are evaluated
577           for superset/subset status, call "is_RsubsetL":
578
579               $RL = is_RsubsetL([ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ], [2,4] );
580
581           or
582
583               $RL = is_RsubsetL( {
584                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
585                   pair  => [ 2, 4 ],
586               } );
587
588       ·   List::Compare::Functional considers two lists to be equivalent if
589           every element in one list appears at least once in R and vice
590           versa.  To determine whether one particular list passed to the
591           function is equivalent to another of the lists passed to the
592           function, provide "is_LequivalentR()" with two array references.
593           The first is a reference to an array of array references, the
594           arrays holding the lists under consideration.  The second of these
595           is a reference to a two-element array consisting of the two lists
596           being tested for equivalence.  A true value (1) is returned if the
597           lists are equivalent; a false value (0) is returned otherwise.
598
599           Example:  To determine whether @Don and @Ed are equivalent, call:
600
601               $eqv = is_LequivalentR(
602                          [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
603                          [3,4]
604                      );
605
606               $eqv = is_LeqvlntR(                                # alias
607                          [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
608                          [3,4]
609                      );
610
611           or
612
613               $eqv = is_LequivalentR( {
614                   items => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
615                   pair  => [3,4],
616               } );
617
618           If no arguments are passed, "is_LequivalentR" defaults to "[0,1]"
619           and compares the first two lists passed to the function. So,
620
621               $eqv = is_LequivalentR( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
622
623           ... translates to:
624
625               $eqv = is_LequivalentR( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ], [0,1] );
626
627       ·   To determine whether any two of the lists passed to the function
628           are disjoint from one another (i.e., have no common members),
629           provide "is_LdisjointR()" with two array references.  The first is
630           a reference to an array of array references, the arrays holding the
631           lists under consideration.  The second of these is a reference to a
632           two-element array consisting of the two lists being tested for
633           disjointedness.  A true value (1) is returned if the lists are
634           disjoint; a false value (0) is returned otherwise.
635
636           Example:  To determine whether @Don and @Ed are disjoint, call:
637
638               $disj = is_LdisjointR(
639                          [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
640                          [3,4]
641                      );
642
643           or
644
645               $disj = is_LdisjointR( {
646                   items => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
647                   pair  => [3,4]
648               } );
649
650       ·   Pretty-print a chart showing the subset relationships among the
651           various source lists:
652
653               print_subset_chart( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
654
655           or
656
657               print_subset_chart( { lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] } );
658
659       ·   Pretty-print a chart showing the equivalence relationships among
660           the various source lists:
661
662               print_equivalence_chart( [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] );
663
664           or
665
666               print_equivalence_chart( { lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ] } );
667
668       ·   Determine in which (if any) of several lists a given string can be
669           found.  Pass two array references, the first of which holds
670           references to arrays holding the lists under consideration, and the
671           second of which holds a single-item list consisting of the string
672           being tested.
673
674               @memb_arr = is_member_which(
675                               [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
676                               [ 'abel' ]
677                           );
678
679           or
680
681               @memb_arr = is_member_which( {
682                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ], # value is arrayref
683                   item  => 'abel',                                 # value is string
684               } );
685
686           In list context, return a list of those indices in the function's
687           argument list corresponding to lists holding the string being
688           tested.  In the example above, @memb_arr will be:
689
690               ( 0 )
691
692           because 'abel' is found only in @Al which holds position 0 in the
693           list of arguments passed to "is_member_which()".
694
695       ·   As with other List::Compare::Functional functions which return a
696           list, you may wish the above function returned a reference to an
697           array holding the list:
698
699               $memb_arr_ref = is_member_which_ref(
700                                   [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
701                                   [ 'jerky' ]
702                               );
703
704           or
705
706               $memb_arr_ref = is_member_which_ref( {
707                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ], # value is arrayref
708                   item  => 'jerky',                                # value is string
709               } );
710
711           In the example above, $memb_arr_ref will be:
712
713               [ 3, 4 ]
714
715           because 'jerky' is found in @Don and @Ed, which hold positions 3
716           and 4, respectively, in the list of arguments passed to
717           "is_member_which()".
718
719           Note:  functions "is_member_which()" and "is_member_which_ref" test
720           only one string at a time and hence take only one element in the
721           second array reference argument.  To test more than one string at a
722           time see the next function, "are_members_which()".
723
724       ·   Determine in "which" (if any) of several lists one or more given
725           strings can be found.  Pass two array references, the first of
726           which holds references to arrays holding the lists under
727           consideration, and the second of which holds a list of the strings
728           being tested.
729
730               $memb_hash_ref = are_members_which(
731                                    [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
732                                    [ qw| abel baker fargo hilton zebra | ]
733                                );
734
735           or
736
737               $memb_hash_ref = are_members_which( {
738                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],  # value is arrayref
739                   items => [ qw| abel baker fargo hilton zebra | ], # value is arrayref
740               } );
741
742           The return valus is a reference to a hash of arrays.  In this hash,
743           each element's value is a reference to an anonymous array whose
744           elements are those indices in the argument list corresponding to
745           lists holding the strings being tested.  In the two examples above,
746           $memb_hash_ref will be:
747
748               {
749                    abel     => [ 0             ],
750                    baker    => [ 0, 1          ],
751                    fargo    => [ 0, 1, 2, 3, 4 ],
752                    hilton   => [    1, 2       ],
753                    zebra    => [               ],
754               };
755
756           Note:  "are_members_which()" tests more than one string at a time.
757           Hence, its second array reference argument can take more than one
758           element.  "is_member_which()" and "is_member_which_ref()" each take
759           only one element in their second array reference arguments.
760           "are_members_which()" returns a hash reference; the other functions
761           return either a list or a reference to an array holding that list,
762           depending on context.
763
764       ·   Determine whether a given string can be found in any of several
765           lists.  Pass two array references, the first of which holds
766           references to arrays holding the lists under consideration, and the
767           second of which holds a single-item list of the string being
768           tested.
769
770               $found = is_member_any(
771                               [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
772                               [ 'abel' ]
773                           );
774
775           or
776
777               $found = is_member_any( {
778                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ], # value is arrayref
779                   item  => 'abel',                                 # value is string
780               } );
781
782           The return value is 1 if a specified string can be found in any of
783           the lists and 0 if not.  In the example above, $found will be 1
784           because "abel" is found in one or more of the lists passed as
785           arguments to "is_member_any()".
786
787       ·   Determine whether a specified string or strings can be found in any
788           of several lists.  Pass two array references, the first of which
789           holds references to arrays holding the lists under consideration,
790           and the second of which holds a list of the strings being tested.
791
792               $memb_hash_ref = are_members_any(
793                                    [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],
794                                    [ qw| abel baker fargo hilton zebra | ]
795                                );
796
797           or
798
799               $memb_hash_ref = are_members_any( {
800                   lists => [ \@Al, \@Bob, \@Carmen, \@Don, \@Ed ],  # value is arrayref
801                   items => [ qw| abel baker fargo hilton zebra | ], # value is arrayref
802               } );
803
804           The return value is a reference to a hash where an element's key is
805           the string being tested and the element's value is 1 if the string
806           can be found in any of the lists and 0 if not.  In the example
807           above, $memb_hash_ref will be:
808
809               {
810                    abel     => 1,
811                    baker    => 1,
812                    fargo    => 1,
813                    hilton   => 1,
814                    zebra    => 0,
815               };
816
817           "zebra"'s value is 0 because "zebra" is not found in any of the
818           lists passed as arguments to "are_members_any()".
819
820       ·   Return current List::Compare::Functional version number:
821
822               $vers = get_version;
823
824   Comparing Lists Held in Seen-Hashes
825       What is a seen-hash?  A seen-hash is a typical Perl implementation of a
826       look-up table:  a hash where the value for a given element represents
827       the number of times the element's key is observed in a list.  For the
828       purposes of List::Compare::Functional, what is crucial is whether an
829       item is observed in a list or not; how many times the item occurs in a
830       list is, with one exception, irrelevant.  (That exception is the
831       "get_bag()" function and its fraternal twin "get_bag_ref()".  In this
832       case only, the key in each element of the seen-hash is placed in the
833       bag the number of times indicated by the value of that element.)  The
834       value of an element in a List::Compare seen-hash must be a positive
835       integer, but whether that integer is 1 or 1,000,001 is immaterial for
836       all List::Compare::Functional functions except forming a bag.
837
838       The two lists compared above were represented by arrays; references to
839       those arrays were passed to the various List::Compare::Functional
840       functions.  They could, however, have been represented by seen-hashes
841       such as the following and passed in exactly the same manner to the
842       various functions.
843
844           %Llist = (
845               abel   => 2,
846               baker  => 1,
847               camera => 1,
848               delta  => 1,
849               edward => 1,
850               fargo  => 1,
851               golfer => 1,
852           );
853           %Rlist = (
854               baker  => 1,
855               camera => 1,
856               delta  => 2,
857               edward => 1,
858               fargo  => 1,
859               golfer => 1,
860               hilton => 1,
861           );
862
863           @intersection = get_intersection( [ \%Llist, \%Rlist ] );
864           @union        = get_union(        [ \%Llist, \%Rlist ] );
865           @complement   = get_complement(   [ \%Llist, \%Rlist ] );
866
867       and so forth.
868
869       To compare three or more lists simultaneously, provide the appropriate
870       List::Compare::Functional function with a first array reference holding
871       a list of three or more references to seen-hashes.  Thus,
872
873           @union = get_intersection( [ \%Alpha, \%Beta, \%Gamma ] );
874
875       The 'single hashref' format for List::Compare::Functional functions is
876       also available when passing seen-hashes as arguments.  Examples:
877
878           @intersection = get_intersection( {
879               lists => [ \%Alpha, \%Beta, \%Gamma ],
880           } );
881
882           @Ronly = get_complement( {
883               lists => [ \%Alpha, \%Beta, \%Gamma ],
884               item  => 3,
885           } );
886
887           $LR = is_LsubsetR( {
888               lists => [ \%Alpha, \%Beta, \%Gamma ],
889               pair  => [ 4, 2 ],
890           } );
891
892           $memb_hash_ref = are_members_any( {
893               lists => [ \%Alpha, \%Beta, \%Gamma ],
894               items => [ qw| abel baker fargo hilton zebra | ],
895           } );
896
897   Faster Results with the Unsorted Option
898       By default, List::Compare::Function functions return lists sorted in
899       Perl's default ASCII-betical mode.  Sorting entails a performance cost,
900       and if you do not need a sorted list and do not wish to pay this
901       performance cost, you may call the following List::Compare::Function
902       functions with the 'unsorted' option:
903
904           @intersection = get_intersection(        '-u',  [ \@Llist, \@Rlist ] );
905           @union        = get_union(               '-u',  [ \@Llist, \@Rlist ] );
906           @Lonly        = get_unique(              '-u',  [ \@Llist, \@Rlist ] );
907           @Ronly        = get_complement(          '-u',  [ \@Llist, \@Rlist ] );
908           @LorRonly     = get_symmetric_difference('-u',  [ \@Llist, \@Rlist ] );
909           @bag          = get_bag(                 '-u',  [ \@Llist, \@Rlist ] );
910
911       For greater readability, the option may be spelled out:
912
913           @intersection = get_intersection('--unsorted',  [ \@Llist, \@Rlist ] );
914
915       or
916
917           @intersection = get_intersection( {
918               unsorted => 1,
919               lists    => [ \@Llist, \@Rlist ],
920           } );
921
922       Should you need a reference to an unsorted list as the return value,
923       you may call the unsorted option as follows:
924
925           $intersection_ref = get_intersection_ref(
926                                   '-u',         [ \@Llist, \@Rlist ] );
927           $intersection_ref = get_intersection_ref(
928                                   '--unsorted', [ \@Llist, \@Rlist ] );
929

DISCUSSION

931   General Comments
932       List::Compare::Functional is a non-object-oriented implementation of
933       very common Perl code used to determine interesting relationships
934       between two or more lists at a time.  List::Compare::Functional is
935       based on the same author's List::Compare module found in the same CPAN
936       distribution.  List::Compare::Functional is closely modeled on the
937       ''Accelerated'' mode in List::Compare.
938
939       For a discussion of the antecedents of this module, see the discussion
940       of the history and development of this module in the documentation to
941       List::Compare.
942
943   List::Compare::Functional's Export Tag Groups
944       By default, List::Compare::Functional exports no functions.  You may
945       import individual functions into your main package but may find it more
946       convenient to import via export tag groups.  Four such groups are
947       currently defined:
948
949           use List::Compare::Functional qw(:main)
950           use List::Compare::Functional qw(:mainrefs)
951           use List::Compare::Functional qw(:originals)
952           use List::Compare::Functional qw(:aliases)
953
954       ·   Tag group ":main" includes what, in the author's opinion, are the
955           six List::Compare::Functional subroutines mostly likely to be used:
956
957               get_intersection()
958               get_union()
959               get_unique()
960               get_complement()
961               get_symmetric_difference()
962               is_LsubsetR()
963
964       ·   Tag group ":mainrefs" includes five of the six subroutines found in
965           ":main" -- all except "is_LsubsetR()" -- in the form in which they
966           return references to arrays rather than arrays proper:
967
968               get_intersection_ref()
969               get_union_ref()
970               get_unique_ref()
971               get_complement_ref()
972               get_symmetric_difference_ref()
973
974       ·   Tag group ":originals" includes all List::Compare::Functional
975           subroutines in their 'original' form, i.e., no aliases for those
976           subroutines:
977
978               get_intersection
979               get_intersection_ref
980               get_union
981               get_union_ref
982               get_unique
983               get_unique_ref
984               get_unique_all
985               get_complement
986               get_complement_ref
987               get_complement_all
988               get_symmetric_difference
989               get_symmetric_difference_ref
990               get_shared
991               get_shared_ref
992               get_nonintersection
993               get_nonintersection_ref
994               is_LsubsetR
995               is_RsubsetL
996               is_LequivalentR
997               is_LdisjointR
998               is_member_which
999               is_member_which_ref
1000               are_members_which
1001               is_member_any
1002               are_members_any
1003               print_subset_chart
1004               print_equivalence_chart
1005               get_bag
1006               get_bag_ref
1007
1008       ·   Tag group ":aliases" contains all List::Compare::Functional
1009           subroutines which are aliases for subroutines found in tag group
1010           ":originals".  These are provided simply for less typing.
1011
1012               get_symdiff
1013               get_symdiff_ref
1014               is_LeqvlntR
1015
1016   April 2004 Change of Interface
1017       Note:  You can skip this section unless you used
1018       List::Compare::Functional prior to the release of Version 0.25 in April
1019       2004.
1020
1021       Version 0.25 initiated a significant change in the interface to this
1022       module's various functions.  In order to be able to accommodate
1023       comparisons among more than two lists, it was necessary to change the
1024       type of arguments passed to the various functions.  Whereas previously
1025       a typical List::Compare::Functional function would be called like this:
1026
1027           @intersection = get_intersection( \@Llist, \@Rlist ); # SUPERSEDED
1028
1029       ... now the references to the lists being compared must now be placed
1030       within a wrapper array (anonymous or named), a reference to which is
1031       now passed to the function, like so:
1032
1033           @intersection = get_intersection( [ \@Llist, \@Rlist ] );
1034
1035       ... or, alternatively:
1036
1037           @to_be_compared = (\@Llist, \@Rlist);
1038           @intersection = get_intersection( \@to_be_compared );
1039
1040       In a similar manner, List::Compare::Functional functions could
1041       previously take arguments in the form of references to 'seen-hashes'
1042       instead of references to arrays:
1043
1044           @intersection = get_intersection( \%h0, \%h1 );
1045
1046       (See above for discussion of seen-hashes.)  Now, those references to
1047       seen-hashes must be placed within a wrapper array (anonymous or named),
1048       a reference to which is passed to the function, like so:
1049
1050           @intersection = get_intersection( [ \%h0, \%h1 ] );
1051
1052       Also, in a similar manner, some List::Compare::Functional functions
1053       previously took arguments in addition to the lists being compared.
1054       These arguments were simply passed as scalars, like this:
1055
1056           @memb_arr = is_member_which(\@Llist, \@Rlist, 'abel');
1057
1058       Now these arguments must also be placed within a wrapper array
1059       (anonymous or named), a reference to which is now passed to the
1060       function, like so:
1061
1062           @memb_arr = is_member_which( [ \@Llist, \@Rlist ], [ 'abel' ] );
1063
1064       ... or, alternatively:
1065
1066           @to_be_compared = (\@Llist, \@Rlist);
1067           @opts = ( 'abel' );
1068           @memb_arr = is_member_which( \@to_be_compared, \@opts );
1069
1070       As in previous versions, for a speed boost the user may provide the
1071       '-u' or '--unsorted' option as the first argument to some
1072       List::Compare::Functional functions.  Using this option, the
1073       "get_intersection()" function above would appear as:
1074
1075           @intersection = get_intersection( '-u', [ \@Llist, \@Rlist ] );
1076
1077       ... or, alternatively:
1078
1079           @intersection = get_intersection( '--unsorted', [ \@Llist, \@Rlist ] );
1080
1081       The arguments to any List::Compare::Functional function will therefore
1082       consist possibly of the unsorted option, and then of either one or two
1083       references to arrays, the first of which is a reference to an array of
1084       arrays or an array of seen-hashes.
1085

AUTHOR

1087       James E. Keenan (jkeenan@cpan.org).  When sending correspondence,
1088       please include 'List::Compare::Functional' or 'List-Compare-Functional'
1089       in your subject line.
1090
1091       Creation date:  May 20, 2002.  Last modification date:  August 16 2020.
1092       Copyright (c) 2002-20 James E. Keenan.  United States.  All rights
1093       reserved.  This is free software and may be distributed under the same
1094       terms as Perl itself.
1095
1096
1097
1098perl v5.32.0                      2020-08-19      List::Compare::Functional(3)
Impressum