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>


Reply via email to