Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I **feel** like this is a stupid questions, but what is the best way to tell if one array is a subset of another
For example, if I have @a1=qw(a b c d e f g) and @a2=qw(b g), then a2 is a subset of a1. Conversly, @a3=qw(e f g h) is not a subset of a1.

thanks

Replies are listed 'Best First'.
Re: Is one array a subset of the other
by halley (Prior) on May 19, 2003 at 19:24 UTC

    As soon as you're thinking of "sets" of unique items and not particularly interested in their order, use hashes.

    Untested.

    my %a1; @a1{qw(a b c d e f g)} = (); my %a2; @a2{qw(b g)} = (); my @a1only = grep { not exists $a2{$_} } keys %a1; my @a2only = grep { not exists $a1{$_} } keys %a2; my @both = grep { exists $a2{$_} } keys %a1; my %u; my @either = grep { not $u{$_}++ } (keys %a1, keys %a2); # your question: print "subset" if not @a2only;

    --
    [ e d @ h a l l e y . c c ]

      Why all the hashes? Array lookups are faster, no? Plus this way you have no extra arrays hanging around. First argument to issubset() is a ref to the big set, second argument is a ref the alleged subset:

      #!/usr/bin/perl use strict; my @a1=qw(a b c d e f g); my @a2=qw(b g); my @a3=qw(c d e f g h); sub issubset { ($a,$b)=@_; for my $x (@$b) { return ("not a subset") unless grep {$x eq $_} @$a; } return ("a subset"); } print "a2 is ",issubset(\@a1,\@a2)," of a1\n"; print "a3 is ",issubset(\@a1,\@a3)," of a1\n"; __END__ Output is: a2 is a subset of a1 a3 is not a subset of a1

      HTH

        Array "lookups" are not faster than hash key lookups. That's the point. It's always O(1) {always takes the same amount of time, regardless of set size} to detect the presence of a key in a hash, while it's O(N) {grows linearly slower as you have more elements} to detect the presence of an element in an array.

        --
        [ e d @ h a l l e y . c c ]

Re: Is one array a subset of the other
by Enlil (Parson) on May 19, 2003 at 19:22 UTC
    Look at the following thread for a similar discussion: Array lookup.

    -enlil

Re: Is one array a subset of the other
by traveler (Parson) on May 19, 2003 at 20:37 UTC
Re: Is one array a subset of the other
by Skeeve (Parson) on May 20, 2003 at 06:42 UTC
    is @a4=qw(b g g); considered a subset? If so how about this solution?
    @a1=qw(a b c d e f g); @a2=qw(b g); @a3=qw(e f g h); print "a1, a2 => ",subset(\@a1, \@a2),"\n"; print "a1, a3 => ",subset(\@a1, \@a3),"\n"; sub subset { my($a1, $a2)= @_; my(%subset); @subset{@$a2}=@$a2; delete @subset{@$a1}; return scalar(keys %subset)==0; }
    It first defines hashkeys for all elements from @a2, then removes all haskeys from @a1. If any haskey remains, @a2 had elements not present in @a1.