Re: match an array element



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
.



Relevant Pages

  • match an array element
    ... I need to match any array element in a list of files. ... for each match recording an hash element like this one: ... Every file is a list of unique words, so I'm sure there will not be problems. ... foreach $file ...
    (perl.beginners)
  • Re: god im a noob
    ... The loop variable of a foreach is ... A DBM hash is stored on disk. ... Each invocation of this subroutine has its own %numbers_colors ...
    (comp.lang.perl.misc)
  • Re: Password scrambler program
    ... foreach { ... You also enter a purpose for the password (such ... Hash(Hash(M), PIN, Site, Purpose, 1) ...
    (sci.crypt)
  • Re: sequence composition
    ... my %s;# a hash of arrays, to hold each line of sequence ... #a hash to hold the AA sequences. ... foreach my $k (keys %seq){ ...
    (perl.beginners)
  • Re: match an array element
    ... for each match recording an hash element like this one: ... > 1) is there a way to avoid a foreach in a foreach? ... $ARGV holds the name of the file currently being read. ... the ARGV filehandle must be closed at eof to reset the line counter $. ...
    (perl.beginners)