Adriano Allora wrote:
> hi all,

Hello,

> I need to match any array element in a list of files. More precisely I'd
> to extract the $. for each match recording an hash element like this one:
> 
> $matches{$filename} = $.
> 
> Every file is a list of unique words, so I'm sure there will not be
> problems.
> My actual solution sounds like:
> 
> foreach $file (@listoffiles)
>     {
>     open (IDX, "<$file") or die "error on $file: $!\n";
>     while(<IDX>)
>         {
>         foreach $word (@listofwords)
>             {
>             $match{$file}= $. if /^$word$/;

You probably need either a Hash of Hashes:

             $match{$file}{$.} = () if /^$word$/;

Or a Hash of Arrays:

             push @{$match{$file}}, $. if /^$word$/;

If you only want to find a single instance of $. for @listofwords then you
should exit the loop as soon as it is found which would be more efficient
unless you only want to find the last occurence of $.?


>             }
>     print "done $file\n" if eof;
>     }

If you put that print *outside* the while loop then you don't have to test for
eof.


>     close(IDX);
>     }
> 
> Two questions:
> 1) is there a way to avoid a foreach in a foreach?

Yes, you could use a single pattern:

my $pattern = qr/@{[ join '|', map "\Q$_", @listofwords ]}/;

{   local @ARGV = @listoffiles;
    while ( <> ) {
        push @{$match{$ARGV}}, $. if /^$pattern$/;
        close ARGV if eof;
        }
    }


> 2) the (possible) other solution is faster than a foreach in a foreach
> or it's only a different way to write it?

It is *usually* faster to use individual patterns (a foreach loop) than to use
one large pattern but you should test it on actual data to be sure:

perldoc Benchmark

perldoc -q "How do I efficiently match many regular expressions at once"



John
-- 
use Perl;
program
fulfillment

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to