in reply to Re: Re: "foreach" is to "next" as "map" is to ???
in thread "foreach" is to "next" as "map" is to ???

The empty list trick, while very cool, is not equivalent to next.
So, there is a difference? Let's see what that should be.
The empty list trick is just preventing the map block from returning a value for that input item - it still has to execut every step in the block first.
Really? Let's see, we take a list of numbers, and for all odd numbers, we print the square of the number, and return the number. The even numbers are skipped. According to your theory, the following code would print the squares of all the numbers:
my @odds = map {$_ % 2 ? do {print $_ * $_; $_} : ()} 1 .. 10;

However, if I run it, it only prints the numbers 1, 9, 25, 49 and 81. I guess either my perl is broken, or your theory is false.

Abigail

Replies are listed 'Best First'.
Re: Re: "foreach" is to "next" as "map" is to ???
by Limbic~Region (Chancellor) on May 26, 2004 at 16:59 UTC
    Abigail,
    If you use a ternary where it branches to the empty list or a do block for each place there is a next statement, then I will buy it doing the same thing.
    # contrived example my @paragraph; for ( @lines ) { next if /^#/; $_ = lc $_; $_ =~ tr/ -~//cd; next if /foobar/; $_ =~ s/administration/admin/g; next if length $_ > 60; push @paragraph, $_; }
    This IMO would be insane for a map block. I stand corrected on the ternary/empty list/do block being functionally equivalent though in sacked's original example there was no do block.

    Cheers - L~R

      though in sacked's original example there was no do block.
      Well, of course there wasn't a do block, because he was showing a foreach loop, and was asking how to do the equivalent using map. You don't need to do {} in the foreach.

      But sacked's original example didn't contain multiple nexts. There's also another way of dealing with this problem: a bare block:

      my @paragraph = map {;{ next if /^#/; $_ = lc $_; $_ =~ tr/ -~//cd; next if /foobar/; $_ =~ s/administration/admin/g; next if length $_ > 60; $_ }} @lines;

      Abigail

        There's also another way of dealing with this problem: a bare block:

        now that's cool

        Cheers - L~R

      I abhor foreach/push loops. Gag me with a spoon!

      my @paragraph = map { local $_ = lc; tr/-~//cd; /foobar/ ? () : do { s/administrator/admin/g; length() > 60 ? () : $_ } } grep /^#/, @lines;

      That code was ugly and I wouldn't have actually written that.

      my @paragraph = map { if ( /^#/ ) { () } else { local $_ = lc; tr/-~//cd; if ( /foobar/ ) { (); } else { s/administration/admin/g; length() > 60 ? () : $_; } } /^#/ ? do { } : (); } @lines;