h3r2on
h3r2on

Reputation: 389

Removing elements from array based on second array

I have a list of filenames prefixes in an array @list1 and a list of full filenames in a second array @list2. In the end I want to end up with a third array containing only full filenames that do not match the prefixes in @list1. I've started with:

for my $match (@list1) {
  @list3 = grep { !/$match/ } @list2;
}

but it doesn't do what I thought it would do. What options do i have to get the result I'm looking for.

Upvotes: 4

Views: 188

Answers (3)

Kenosis
Kenosis

Reputation: 6204

Perhaps an alternation regex will help:

use strict;
use warnings;

my @list1 = qw/a.f c data g j/;
my @list2 = qw/myfile.txt a.file.txt data.txt otherfile.txt jargon.txt/;

my $regex = join '|', map "\Q$_\E", @list1;

my @list3 = grep !/^(?:$regex)/, @list2;

print "$_\n" for @list3;

Output:

myfile.txt
otherfile.txt

Upvotes: 5

memowe
memowe

Reputation: 2668

If you want to use a more list-expression-like way (as in your example), you could work with this:

#!/usr/bin/env perl

use strict;
use warnings;
use List::Util 'first';
use feature 'say';

my @filenames = qw(foo bar baz quux alice bob);
my @forbidden = qw(f ba);

my @matching  = grep {
    my $filename = $_;
    not defined first { $filename =~ /^\Q$_/ } @forbidden;
} @filenames;

say for @matching;

Output:

quux
alice
bob

Note: I used first here instead of the core-grep because with long @forbidden lists it could be more efficient since it stops after the first (and possibly only) match.

Upvotes: 1

reo katoa
reo katoa

Reputation: 5801

#!/usr/bin/perl

use strict;
use warnings;

my @prefixes = qw(a b d);
my @items = qw(apple banana cow dog fruitcake orangutan crabcake deer);

my @nonmatching;
ITEMS: foreach my $item (@items) {
    foreach my $prefix (@prefixes) {
        next ITEMS if ($item =~ /^$prefix/)
    }
    push @nonmatching, $item
}

$,=$\="\n";
print @nonmatching;

yields

cow
fruitcake
orangutan
crabcake

Edited as per raina77ow's suggestions.

Upvotes: 0

Related Questions