Home > Net >  How do I put a conditional and a loop in the same line?
How do I put a conditional and a loop in the same line?

Time:02-12

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);
  •  Tags:  
  • perl
  • Related