iphone has asked for the wisdom of the Perl Monks concerning the following question:

I have an array "@files" which contain all the lines in a file.Some of the contents of the array ends with .plf like

//source/embark/load.c //deploy//common.c //depot/scripts/files/loading.plf

....

Now I have the below hash "Hash_filematches",I want to execute the loop for only the keys (btw,keys in this hash only contain filenames with .plf extension)*not* in the array @files.How to i write this condition?

for my $key (keys %Hash_filematches) { if ($key !=~ /grep (/$key/i, @files/) {#grepping for the key value + and if it's not in the array then only proceed } }

Replies are listed 'Best First'.
Re: Grep fail condition
by ELISHEVA (Prior) on Nov 07, 2010 at 22:00 UTC

    In general

    • any Perl function or subroutine that returns an array can return a count instead by prefixing it with scalar. Thus:
      • scalar @aFiles returns the number of items in @aFiles
      • scalar grep returns the number of matches instead of the actual matches.
      • scalar keys returns the number of keys in a hash rather than the actual keys.
    • if you need to match the entire value, start your regex with ^ and end it with a $. /a/ matches any string with the letter a. /^a$/ matches only the string "a".
    • next if ... lets you skip a loop iteration if whatever comes after "if" is true

    So applying this to you little code snippet:

    for my $k (sort keys %$hFiles) { # ^$k$ forces $k to match the entire value of each entry in @aFiles # - ^ forces match at start of entry # - $ forces match at end of entry # - ^$k$ expands to whatever is in $k, # i.e. $k="x", then expands to ^x$ # # next if scalar grep... will go back to start of loop whenever one # or more values match # - scalar grep - returns number of matches # - next goes back to start of loop next if scalar grep( /^$k$/, @aFiles); print "key=$k\n"; }

    For more information, see scalar and perlre

    Best, beth
      next if scalar grep( /^$k$/, @aFiles);

      if already imposes scalar context on its operand.

Re: Grep fail condition
by ikegami (Patriarch) on Nov 07, 2010 at 20:47 UTC
    if (my @matching_files = grep /\Q$key/i, @files) { ... }

      I want to enter the loop when the grep *fails*.The below condition enters the loop when the grep passes

      if (my @matching_files = grep /\Q$key/i, @syncsource_plf) { ... }
        if ( not grep { condition } list ) {
Re: Grep fail condition
by aquarium (Curate) on Nov 07, 2010 at 22:24 UTC
    if the size of the hash is much smaller than the array, by order of magnitude. then it would be more efficient to loop the other way around. that is, loop through the array. it might make also make it more natural/fitting in certain circumstances as well, depending on more program context.
    if the array grows to "huge" size. it might make it more efficient or at least easier to manage, to pre-process the array to add hash keys of any .plf or other filenames of interest, at each position in the array. e.g. $files[200]{'filename'}{'something.plf'}=1; OR other some structure to get similar effect.
    the hardest line to type correctly is: stty erase ^H
Re: Grep fail condition
by Anonymous Monk on Nov 07, 2010 at 20:29 UTC