Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

array filter

by Anonymous Monk
on Nov 18, 2008 at 07:49 UTC ( [id://724210]=perlquestion: print w/replies, xml ) Need Help??

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

Hi all! How do I filter array strings stripping out from them other strings listed in another array. In pseudo-code:
foreach @filterarray { if @mainarray element contains @filterarray element { strip out @filterarray element from @mainarray element} }
Result should be @mainarray with all the original elements, but purged of @filterarray elements. So, if @filterarray contains "the" and @mainarray contains "In to the wild" or "The catcher in the rye", after the job they should look like "In to wild" and "catcher in rye". Any help greatly appreciated. Thanks in advance.

Replies are listed 'Best First'.
Re: array filter
by ikegami (Patriarch) on Nov 18, 2008 at 08:09 UTC
    my ($filter_re) = map qr/$_/, join '|', map quotemeta, @filters; for my $phrase (@phrases) { $phrase =~ s/$filter_re//ig; }
    or
    use Regexp::List qw( ); my $filter_re = Regexp::List ->new(modifiers => 'i') ->list2re(@filters); for my $phrase (@phrases) { $phrase =~ s/$filter_re//g; }

    The second should be faster is Perls earlier than 5.10.

    Update: Made case-insensitive.

      Or did you mean

      @mainarray contains "In", "to", "the", wild"

      Use grep to filter out array elements.

      my %filters = map { lc($_) => 1 } @filters; my @words = grep !$filters{lc($_)}, @words;
Re: array filter
by why_bird (Pilgrim) on Nov 18, 2008 at 08:10 UTC

    First of all, try super search. There are lots of nodes out there that ask similar questions. Here is the one, for example that I picked off the top of the list.

    Now, I'm sure there are better ways of doing this, but the simple implementation just iterates over both arrays and uses splice.

    #! /usr/bin/perl use strict; use warnings; use Data::Dumper; my @array=qw(In to the wild); my @filterarray=qw(the); print Dumper @array; for(my $i=0;defined $array[$i];$i++){ my $word=$array[$i]; foreach my $filter (@filterarray){ if($filter eq $word){ splice (@array,$i,1); } } } print Dumper @array; exit 0;

    In case you're not familiar, Data::Dumper is your friend when it comes to quickly printing out output, especially arrays and hashes. 'qw' means separate whatever's inside the brackets and put them in single quotes (no variable interpolation). So qw(Into the wild) -> ('Into', 'the', 'wild'). And always use strict and use warnings.

    hope that helps
    why_bird

    ........
    Those are my principles. If you don't like them I have others.
    -- Groucho Marx
    .......
Re: array filter
by LanX (Saint) on Nov 18, 2008 at 10:11 UTC
    So, yo are studying computer linguistics? ; )
    -> searching in array elements substrings contained in another array

    Ikegami's solution to build up a big filter-regex might be faster, but maybe this one is just simpler

    @main=("In to the wild" ,"The catcher in the rye") ; @filters=("the","in"); for $filter (@filters) { s/\Q$filter\E//ig for @main; } print "@main"; # to wild catcher rye
    (tested in perlshell)

    \Q and \E are for quoting possible regexcode in @filter. If you want to get rid of whitespaces or dupplicate replacements and so on just improve the regex, it's up to you!

    Cheers LanX

    - - - - - Which song???

      Thanks to all. I tried to use the suggested solutions, but it seems I have not well specified what I meant: the words included in @filter must match when they're not embedded in other words... Using the code above, when @filter meets a phrase in @main that contains, for example, "Ethernet", it strips out "the" and it returns "Ernet" , and that's not what I meant... Sorry if I was unclear.. I tried anyway to do :
      for $filter (@filters) { s/\Q\b$filter\b\E//ig for @main; }
      adding the \b bound delimiter, but still it doesn't work. How should I improve the regex to obtain what I need? Thank you again.
        \b should be OK, but your escaping it within \Q and \E !!!

        Cheers LanX

        - - - - - Which song???

        > .. Sorry if I was unclear.. I

        no prob, a certain unclearity was obvious and the reason why I gave you a simple and expandable approach to start with. 8 )

        So, did you already think about the whitespaces left? ; )

        You may want to consider \s* instead of \b.

        When speed is a matter think about tuning the final solution like ikegami showed you!

        Cheers LanX

        - - - - - Which song???

Re: array filter
by MidLifeXis (Monsignor) on Nov 18, 2008 at 17:52 UTC

    Is this homework?

    --MidLifeXis

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://724210]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (2)
As of 2024-04-20 06:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found