Hi Booger,

You can use grep and map to achieve a shorter, terser form of a loop, if that's what you want to do.  One reason I like map is that it feels more natural to put the entirety of a map block on a single line.  This may or not be want you want, depending on your taste, how clear you want the code to be, or a variety of other factors.

Let's say you have a simple array of numbers and want to pull all the odd numbers out of it into a separate array.  You can do this in a variety of ways:

use strict; use warnings; my @nums = ( 1, 2, 3, 8, 19, 31, 42, 77, 113, 121, 144 ); my @odds; # 1. Get odd numbers using "for" for (my $i = 0; $i < @nums; $i++) { if (0 != $num[$i] % 2) { push @odds, $_; } } # 2. Get odd numbers using "foreach" foreach (@nums) { ($_ % 2) and push @odds, $_; } # 3. Get odds using "grep" @odds = grep { 0 != ($_ % 2) } @nums; # 4. Get odds using "map" @odds = map { ($_ % 2)? $_: () } @nums; # 5. Demonstrate the folly of breaking out of "map" with "last" @odds = map { ($_ % 2)? $_: last } @nums;

In #1, a for loop is used to iterate through the array, pushing each value onto the array odd only if it's odd.

In #2, a foreach loop is used to do the same thing.  Either of #1 or #2 could be short-circuited in the middle of the loop with last; for example, you could use last to stop at the first odd value.

In #3, a grep is used to achieve the same results; creating the array odd.

In #4, using a map demonstrates that map is very similar to a grep.  Notice how cleanly #3 and #4 fit on one line.  You could do the same with a foreach:

foreach (@nums) { ($_ % 2) and push @odds, $_ }

but the convention is to use separate lines instead, partially because it's more verbose, and might be considered easier to read or add comments to (because of the extra whitespace).

Finally, #5 above shows why you can't short-circuit using last; it's explicitly forbidden:

Can't "last" outside a loop block at last_test.pl line 27.
While you may or may not agree that it should be legal to do, you now know that, if you *have* to short-circuit, you should stick to one of the other types of loop instead.

s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

In reply to Re: Ways to control a map() operation by liverpole
in thread Ways to control a map() operation by Booger

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.