Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

using next in a nested foreach()

by sandrider (Acolyte)
on Aug 16, 2005 at 00:57 UTC ( [id://484035]=perlquestion: print w/replies, xml ) Need Help??

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

Dear monks,

I have this nested foreach loop

foreach $one (@one) { foreach $two (@two) { $one =~ m/\(.\)(.+)\(.\)/; if ($two eq $1) { push @result, $one; } } }

I need the script to go to the parent foreach loop when $two eq $1, I've tried putting next in the if but it just goes to the next field in the child foreach.

Thanks.

Desmond

Replies are listed 'Best First'.
Re: using next in a nested foreach()
by gryphon (Abbot) on Aug 16, 2005 at 01:36 UTC

    Greetings sandrider,

    In addition to using labels as two other monks have suggested already, you could use last to exit the inner loop, thus nexting to the outer loop.

    foreach my $one (@one) { $one =~ m/\(.\)(.+)\(.\)/; foreach my $two (@two) { if (($1) and ($two eq $1)) { push @result, $one; last; } } }

    TMTOWTDI.

    Update: I moved the m// outside the inner foreach due to japhy's comment. No idea why I didn't see that before. Doh.

    gryphon
    Whitepages.com Development Manager (DSMS)
    code('Perl') || die;

      This solution, of course, doesn't help with existing deeply nested loops. That's where the labels come in really handy. There is the caveat that the misuse of labels can cause very odd behavior (like the sudden termination of you script) if you are not careful (typos).

      Also, to further optimize (typing optimization; not necessarily execution optimization) based on japhy's comment, you could try this instead:

      push @results, grep { grep { $1 eq $_ } @two if ( $_ =~ /\(.\)(.+)\(.\)/ ) } @one;
      You get to use a nested grep, but you check all values of @two and don't stop when you find a match.

      Update: Since grep will localize $_ and I don't need the outer $_ in the inner grep, I optimized away reassigning the outer $_;

      Ivan Heffner
      Sr. Software Engineer, DAS Lead
      WhitePages.com, Inc.
Re: using next in a nested foreach()
by jhourcle (Prior) on Aug 16, 2005 at 01:01 UTC

    Use labels:

    PARENT: foreach $one (@one) { foreach $two (@two) { $one =~ m/\(.\)(.+)\(.\)/; if ($two eq $1) { push @result, $one; next PARENT; } } }

    Odd are, at least three other people will post the exact same thing before I hit 'create'

Re: using next in a nested foreach()
by GrandFather (Saint) on Aug 16, 2005 at 01:07 UTC

    See "Loop Control" in perlsyn


    Perl is Huffman encoded by design.
Re: using next in a nested foreach()
by japhy (Canon) on Aug 16, 2005 at 13:01 UTC
    Nobody mentioned the obvious (to me).

    Move the $one =~ m/.../ line outside of the inner for-loop. There's no reason to do the same thing over and over and over.


    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: using next in a nested foreach()
by sandrider (Acolyte) on Aug 16, 2005 at 03:15 UTC
    Thanks guys for all the help.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2024-04-20 07:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found