map doesn't have special words like "last" or "next". It is really intended for situations where you want to process every single element, not for situations where you want to process just up until the first match to something or other. When you want to stop immediately on some condition your first solution, using a foreach loop is really the best choice.

However, if you really, really must use map (and I don't recommend this), you can place map inside of an eval {...} clause and "return" when you find your stop condition. Part of the attraction of map is its succinctness. As you can see from the example below, placing map inside eval {...} takes that away. More importantly, experienced Perl coders expect to see foreach or while statements when you want to "loop until stop condition" so it might take them by surprise. Taking people by surprise can really cost you need help tracking down a sneaky bug.

Normally using "return" in a map statement causes you to exit whatever sub you are currently in -- or your entire script(!) if you aren't in a sub. You probably don't want that. However, if you surround map with eval { ... } you will only leave the eval block.

#stop condition is the first empty line. use strict; use warnings; sub mapInEval { my $content = shift; my @lines; my $result; eval { # leaves eval loop, not sub @lines = map { /^$/ ? return : $_ } split /\n/, $content; return 1; }; print "non empty lines: <@lines>\n"; } sub mapNotInEval { my $content = shift; my @lines; my $result; # leaves the sub !!!! @lines = map { /^$/ ? return : $_ } split /\n/, $content; print "non empty lines: <@lines>\n"; } my $spacey = <<__EOF__; Do Re Mi __EOF__ my $notSpacey = <<__EOF__; A B C __EOF__ print "WITH eval { ... } around map\n"; print "testing spacy: "; mapInEval($spacey); print "\ntesting not spacy:"; mapInEval($notSpacey); print "------------------------------\n"; print "WITHOUT eval { ... } around map\n"; print "testing spacy: "; mapNotInEval($spacey); print "\ntesting not spacy:"; mapNotInEval($notSpacey);

Best, beth

Update: added further explanation about why using eval { map } isn't really recommended.


In reply to Re: Improve foreach with help of map? by ELISHEVA
in thread Improve foreach with help of map? by mickep76

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.