Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

nested loops and next

by jonnyfolk (Vicar)
on Sep 03, 2014 at 20:18 UTC ( #1099466=perlquestion: print w/replies, xml ) Need Help??

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

I have a for loop nested within a hash loop. If the push to @groups is performed I want the for loop to exit and the hash loop to move onto the next key. I think I should be using next, but where to put it?

while ( my ($key, $value) = each %ids ) { for my $item (@names) { if ($item =~ /$key/) { push @groups, $item; } } }

Replies are listed 'Best First'.
Re: nested loops and next
by GrandFather (Saint) on Sep 03, 2014 at 20:58 UTC

    An alternative to Applefritter's suggestion is:

    while (my ($key, $value) = each %ids) { for my $item (@names) { next if $item !~ /$key/; push @groups, $item; last; } }

    which avoids a level of nesting and maybe provides a stronger hint that the task of the current loop is done.

    I this case saving a level of nesting by using an "early exit" doesn't make much difference. But this technique scales very well so when the code that would be inside the if statement becomes larger and includes its own nested code program flow is much easier to see.

    The same sort of technique can be used in subs by using return to exit early (hence the name). Used well and combined with dealing with simple cases first program flow is generally much easier to see and understand.

    Perl is the programming world's equivalent of English
Re: nested loops and next
by AppleFritter (Vicar) on Sep 03, 2014 at 20:25 UTC

    Use a label on your while loop:

    HASH: while(my ($key, $value) = each %ids) { for my $item (@names) { if($item =~ m/$key/) { push @groups, $item; next HASH; } } }

    Alternatively, you could also use last to exit the inner loop and let things take their natural course, as it were.

Re: nested loops and next
by jonnyfolk (Vicar) on Sep 03, 2014 at 20:35 UTC
    Thanks very much. I haven't come across labelling before, I'll check it out!!

      You're welcome! Labels are discussed in Compound Statements in perlsyn, BTW:

      The LABEL is optional, and if present, consists of an identifier followed by a colon. The LABEL identifies the loop for the loop control statements next, last, and redo. If the LABEL is omitted, the loop control statement refers to the innermost enclosing loop.

      Contrary to what that document appears to imply, though, labels can be used on any statement; outside of loops, you'll want to use goto to jump to them. (Or perhaps not want to, if you're a monk of the Dijkstraian persuasion.)

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (3)
As of 2021-09-28 04:59 GMT
Find Nodes?
    Voting Booth?

    No recent polls found