in reply to if block inside map

@x = map { if ($_ > 1) { 1 } } (-5 .. 5)
But trying to read your mind, I suppose you need rather
@x = map { if ($_ > 1) { 1 } else { 0 } } (-5 .. 5)
which can be also written with the ternary operator:
@x = map { $_ > 1 ? 1 : 0 } (-5 .. 5)

Replies are listed 'Best First'.
Re^2: if block inside map
by Eliya (Vicar) on Nov 11, 2011 at 17:42 UTC

    Just to elaborate a little.  You can also leave off the else branch, in which case map would return the empty string (not sure why not undef) when the if-condition isn't true:

    my @x = map { if ($_ > 0) { $_*2 } } (-2 .. 2); use Data::Dumper; print Dumper \@x; __END__ $VAR1 = [ '', '', '', 2, 4 ];

    When you don't want to return anything in those cases, you can use the empty list ():

    my @x = map { if ($_ > 0) { $_*2 } else { () } } (-2 .. 2); # or: my @x = map { $_ > 0 ? $_*2 : () } (-2 .. 2); use Data::Dumper; print Dumper \@x; __END__ $VAR1 = [ 2, 4 ];

        Thanks for the pointer.  I must admit that thread somehow happened to sneak out from under my radar :)

        Personally, I would consider it more "natural" if an if-construct without an else clause (when used in an "expression context") would sematically behave more like a ternary cond ? ... : undef (instead of cond ? ... : cond), but if you look at it from the perspective of what is evaluated last, it's of course perfectly clear why things behave as they do.

        (Yes, I'm aware that if-constructs in Perl - unlike in some other languages - don't evaluate to anything itself (as a whole), i.e. they are not expressions — so no need to comment on that.)

Re^2: if block inside map
by taiko (Sexton) on Dec 08, 2015 at 11:53 UTC
    ouh man, you made my day with this. Specially with ternary operator

      Other ways:

      • If you can use empty strings instead of zeros in the output list (i.e., you're not doing arithmetic with the elements of the output),
        then either  map { $_ > 0 } or just  map $_ > 0, (note the terminating comma) will do the trick:
        c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "my @x = map $_ > 1, -3 .. 3; dd \@x; " ["", "", "", "", "", 1, 1]
      • If you gotta have 0s,  || or  or will do:
        c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "my @x = map { $_ > 1 or 0 } -3 .. 3; dd \@x; " [0, 0, 0, 0, 0, 1, 1]
        (Note that  map $_ > 1 || 0, -3 .. 3 would also work, but  map $_ > 1 or 0, -3 .. 3 will not. Can you say why? This is one reason why some Best Practices recommend avoiding the  map EXPR, LIST form of map.)
      • And of course, there are other ways...


      Give a man a fish:  <%-{-{-{-<