Adriano Allora wrote:
>
> 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$/;
> }
> print "done $file\n" if eof;
> }
> close(IDX);
> }
>
> Two questions:
> 1) is there a way to avoid a foreach in a foreach?
> 2) the (possible) other solution is faster than a foreach in a foreach
> or it's only a different way to write it?
To check for a matching word you should be using
$match{$file} = $. if $_ eq $word;
rather than the expensive regex. Bear in mind that you need to chomp() each
record before the comparison though as otherwise it will have a trialing newline
and won't match when it should.
A hash is ideal for checking to see if a given word is in a list of words and
speeds up the process enormously.
Assigning a list of files to @ARGV makes Perl behave as if they were entered on
the command line. It will then magically handle the file opens for you and
simplify your program.
This solution creates a hash %words with keys equal to the words in @listofwords
(the values are all undefined since we're not using them). Each line of each
file is then chomped and the %match hash interrogated to see if an element with
such a key exists. $ARGV holds the name of the file currently being read.
Finally, the ARGV filehandle must be closed at eof to reset the line counter $.
at the start of the subsequent file.
HTH,
Rob
my %words;
@[EMAIL PROTECTED] = ();
@ARGV = @listoffiles;
while (<>) {
chomp;
$match{$ARGV} = $. if exists $words{$_};
if (eof) {
print "done $ARGV\n";
close ARGV;
}
}
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>