Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Construct for Skipping and Continue

by monkfan (Curate)
on Feb 23, 2007 at 02:18 UTC ( [id://601670]=perlquestion: print w/replies, xml ) Need Help??

monkfan has asked for the wisdom of the Perl Monks concerning the following question:

Dear experts,
Suppose I have the following array and marker:
my @arr = qw( bar qux foo qux2 bar2 foo foo3 ); my $marker = "foo";
What I intend to do is to print all the elements of the array starting from marker first found to the end of the array. Yielding:
foo qux2 bar2 foo foo3
Thus skippping the first two elements of the array ("bar" and "qux"). What's the best construct to achieve that? I've tried the following, but it doesn't give the result I desired:
my @arr = qw( bar qux foo qux2 bar2 foo foo3 ); my $marker = "foo"; foreach my $arr (@arr) { next unless ($arr eq $marker); print "$arr\n"; } continue { print "$arr\n"; }

Regards,
Edward

Replies are listed 'Best First'.
Re: Construct for Skipping and Continue
by GrandFather (Saint) on Feb 23, 2007 at 02:53 UTC

    That's what the range operator (see perlop) was designed for:

    use warnings; use strict; my @arr = qw( bar qux foo qux2 bar2 foo foo3 ); my $marker = "foo"; for (@arr) { next unless $_ eq 'foo' .. undef; print "$_\n"; }

    Prints:

    foo qux2 bar2 foo foo3

    DWIM is Perl's answer to Gödel
Re: Construct for Skipping and Continue
by imp (Priest) on Feb 23, 2007 at 02:32 UTC
    You would typically use a flag for whether the item was found or not. For example:
    use strict; use warnings; my @arr = qw( bar qux foo qux2 bar2 foo foo3 ); my $marker = "foo"; my $found = undef; for my $entry (@arr) { if ($entry eq $marker) { $found = 1; } if (defined $found) { print $entry, "\n"; } }
    Alternately if you want to extract the subset:
    use strict; use warnings; my @arr = qw( bar qux foo qux2 bar2 foo foo3 ); my $marker = "foo"; print "$_\n" for items_after($marker, @arr); sub items_after { my ($marker, @list) = @_; my $index = 0; for my $entry (@list) { print "Checking '$entry' eq '$marker'\n"; if ($entry eq $marker) { return @list[$index..$#list]; } $index++; } return; }
Re: Construct for Skipping and Continue
by Zaxo (Archbishop) on Feb 23, 2007 at 03:00 UTC

    The scalar range operator, or flip-flop, is handy for constructs like this:

    my @arr = qw( bar qux foo qux2 bar2 foo foo3 ); my $marker = "foo"; for (@arr) { print $_, $/ if ($marker eq $_) .. 1; } __END__ foo qux2 bar2 foo foo3
    That makes the decision to print be carried by the state of the range operator. A simpler loop results.

    GrandFather++

    After Compline,
    Zaxo

      Watch that .. 1 if you happen to be reading from a file at any point during the script. Interesting things could happen! From the perlop documentation for 'Range Operators':

      If either operand of scalar ``..'' is a constant expression, that operand is considered true if it is equal (==) to the current input line number (the $. variable).

      DWIM is Perl's answer to Gödel
Re: Construct for Skipping and Continue
by rhesa (Vicar) on Feb 23, 2007 at 02:52 UTC
    my @arr = qw( bar qux foo qux2 bar2 foo foo3 ); my $marker = "foo"; my $seen_marker; my @wanted = grep { $seen_marker ||= ($_ eq $marker) } @arr; print "@wanted"; __END__ foo qux2 bar2 foo foo3

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://601670]
Approved by imp
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (6)
As of 2024-04-19 18:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found