I would like to put a conditional and loop on the same line on Perl. This is what I would like to achieve:
foreach (0 .. 10) {
print $_ if $_ % 2;
}
which should give me 13579
. I'm looking for a statement like loop comprehension in Python, e.g.
[i for i in range(10) if i % 2]
I know that print $_ foreach 0 .. 10;
works but the problem is adding the conditional to the statement as well...
CodePudding user response:
For elements of a list which are odd
$_%2 and print for 0..10;
or for elements at odd indices
$_&1 and print for 0..10;
Here 0..10
would stand for array (@ary
) indices, like
my @ary = 0..10;
$_&1 and print $ary[$_] for 0..$#ary;
The syntax $#ary
is for the index of the last element of array @ary
.
Assuming that you indeed need array elements at odd indices can also do
my @ary = 0..10;
print for @ary[grep { $_&1 } 0..$#ary];
The point being that Perl's and
short-circuits so if the expression on its left-hand-side isn't true then what is on its right-hand-side doesn't run. (Same with or
-- if the LHS is true the RHS isn't evaluated.)
All above print 13579
(no linefeed). In a one-liner, to enter and run on the command-line
perl -we'$_%2 and print for 0..10'
If you actually need to print each number on its own line, judged by a posted comment, replace print
with say
(and enable that feature by use feature 'say';
in a program), like
$_%2 and say for 0..$#ary;
for odd array elements from array @ary
, or
$_&1 and say $ary[$_] for 0..$#ary;
for array elements at odd indices.
Add use feature 'say';
to the beginning of the program (unless it is enabled already by other features/modules).
CodePudding user response:
Perl isn't Python. List comprehensions are nice, but Perl doesn't have them.
The closest perl idiom is probably something like
grep $_ % 2 , (0..9);
A 1-liner to try it out:
$ perl -e '@a = grep $_ % 2 , (0..9); print "@a\n"'
1 3 5 7 9
Note there's probably a performance difference in both memory and time. I'm pretty sure Perl will build the complete list of 10 items and filter it to make a new list. The list comprehension can build the filtered list directly.
CodePudding user response:
Why not something like below?
#! /usr/bin/env perl
use warnings;
use strict;
use utf8;
use feature qw<say>;
print ($_ % 2 ? $_ : "") for (1..10);
exit(0);