No one has mentioned the CPAN modules that help solve this sort of problem: List::Compare, Set::Scalar, and Set::Array. If "elements in exactly 2 lists" was the only 'set' operation in a program, I would use jhourcle's second solution. If more than one 'set' operation is needed, the modules start to really pay off.

Set::Scalar has a flexible syntax, allowing for a dense mix of overloaded operators and chained methods. It can solve the OP problem quite tersely:

use strict; use warnings; my @array1 = ( 1, 2, 5, 9, 11, 12, 13 ); my @array2 = ( 1, 2, 5, 11, 12, 13 ); my @array3 = ( 1, 2, 5, 7, 9, 12, 13 ); use Set::Scalar; my $x = Set::Scalar->new(@array1); my $y = Set::Scalar->new(@array2); my $z = Set::Scalar->new(@array3); # Either way works. #my $answer = $x->union($y,$z) # - $x->unique($y,$z) # - $x->intersection($y,$z); my $answer = ($x + $y + $z) - ($x / $y / $z) - ($x * $y * $z); my @only_two = $answer->elements();

List::Compare is better for a generalized form of the OP problem (find elements occurring exactly N times in X lists). In addition to the expected set functions (get_intersection, get_symmetric_difference, etc.), it provides are_members_which, which builds a hash like this:

{ 1 => [ 0, 1, 2 ], 2 => [ 0, 1, 2 ], 5 => [ 0, 1, 2 ], 7 => [ 2 ], 9 => [ 0, 2 ], 11 => [ 0, 1 ], 12 => [ 0, 1, 2 ], 13 => [ 0, 1, 2 ], }
The number of elements in each of those value arrays is equal to the number of lists where key is found.
use List::Compare; sub elements_found_in_exactly_n_lists { my ($n, @array_refs) = @_; my $lc = List::Compare->new(@array_refs); my @u = $lc->get_union(); my %h = %{ $lc->are_members_which(\@u) }; return grep { @{$h{$_}} == $n } keys %h; } my @only_two = elements_found_in_exactly_n_lists( 2, \@array1, \@array2, \@array3, );


In reply to Re: array comparison question by Util
in thread array comparison question by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.