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

The following line of code is from Stein's "Official Guide to Programming with CGI.pm", (page 73).
grep ($fields{$_}++, @fields);
I understand what the code is doing (ie: setting the keys for the hash %fields equal to the elements in the array @fields). What I don't understand is why it works. What is the autoincrement doing? Can anyone explain this?

Thanks.

Replies are listed 'Best First'.
Re: Use of grep with arrays/hashes
by merlyn (Sage) on May 24, 2001 at 01:59 UTC

      The reason for this, if I may venture a theory, is that using grep to loop through an array is contrary to grep's desired use. grep is used to return an array of matches from a supplied array of candidates.

      The example posted uses grep for it's side effects (ie, executing code in the grep BLOCK that has nothing to do with testing the validity of the candidate elements in the array.

      but why do you need ++ since even undef does not remove a key?
Re: Use of grep with arrays/hashes
by geektron (Curate) on May 24, 2001 at 01:54 UTC
    the autoincrement adds one to the hash VALUE.

    also read: $hash{$field} = 1; since the original value of $hash{$field} is 0 ( or undef, i forget which ).

      A hash value for a key that doesn't exist is referred to as being "undefined". Not surprisingly, the value returned by $hash{"non-existent"} is undef. It's just that undef+1 is 1.

      xoxo,
      Andy

      %_=split/;/,".;;n;u;e;ot;t;her;c; ".   #   Andy Lester
      'Perl ;@; a;a;j;m;er;y;t;p;n;d;s;o;'.  #   http://petdance.com
      "hack";print map delete$_{$_},split//,q<   andy@petdance.com   >
      
Re: Use of grep with arrays/hashes
by Anonymous Monk on May 25, 2001 at 13:02 UTC
    I will point out, that the grep form returns an array of the multiple values in the array.
Re: Use of grep with arrays/hashes
by DeaconBlues (Monk) on May 24, 2001 at 06:38 UTC

    I prefer to use the map function for this type of hash population

    map {$fields{$_}++} @fields;

    This is not much different than merlyn's; his is probably faster though. I wonder why ...

      Of the two bad idioms, abusing map is worse because if your function returns multiple values per term and you are on any Perl before 5.6.1, the effort of constructing the return list is quadratic.

      But map and grep work out the same in this case, and the potential difference is largely irrelevant because both run more slowly than simple looping and waste more memory while they are at it. So use a loop.