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>