http://qs321.pair.com?node_id=153402

fuzzball has asked for the wisdom of the Perl Monks concerning the following question: (arrays)

I need to take a array of URL's in @A, compare it to a array of "banned" domain names in @B, and either remove matches from @A, or put non-matches into a new array, @C. Given example data:
@A = ( 'yahoo.com', 'altavista.com', 'yahoo.com/index.html' ); @B = ( 'yahoo.com', 'webcrawler.com' );
@A (or @C) should end up with only 'altavista.com'. Clearly, it is has to match with patterns, not just exact string equality.

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: How Do I Compare Array A to Array B, removing B elements from A.
by merlyn (Sage) on Mar 21, 2002 at 21:03 UTC
    my @C; OUTER: for ( @A ) { for my $pat ( @B ) { if ( /\Q$pat/i ) { next OUTER; } } push @C, $_; }

      other strategy for above solution is.
      @array_one = qw(one two three four); @array_two = qw(three four five six); %array_one = map {$_, 1} @array_one; @difference = grep {!$array_one {$_}} @array_two; print "@difference\n";
Re: How Do I Compare Array A to Array B, removing B elements from A.
by dragonchild (Archbishop) on Mar 21, 2002 at 20:15 UTC
    Something like:
    my @C = grep { my $x = $_; not grep { $x =~ /\Q$_/i } @B } @A;
Re: How Do I Compare Array A to Array B, removing B elements from A.
by SavannahLion (Pilgrim) on Jan 16, 2006 at 15:48 UTC
    For anybody who comes after me, I'd like to point out in the first above example by dragonchild a minor correction. When I copied the example, I was losing the data pushed into @ArrayC. Adding a pair of ( ) on the line with grep solves the problem.
    my @ArrayC = map { my $x = $_; (grep { $x =~ /^$_/ } @ArrayB) ? () : $x } @ArrayA;
    I don't know if it's a typo or a change in how Perl handles the expression. I figure this note will help save someone fifteen minutes of frustration.

    Originally posted as a Categorized Answer.

Re: How Do I Compare Array A to Array B, removing B elements from A.
by knobunc (Pilgrim) on Mar 21, 2002 at 21:06 UTC

    It might be more efficient (depending on the sizes of the 2 arrays) to make a hash from one to do a quick lookup:

    my %HashB = map { ($_ => 1) } @ArrayB; @ArrayA = grep { $HashB{$_} } @ArrayA;

    -ben

    Originally posted as a Categorized Answer.