in reply to Ways to control a map() operation
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:
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.Can't "last" outside a loop block at last_test.pl line 27.
|
|---|