Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy - how to exit each loop?

Tags:

xml

grails

groovy

I'm new to Grails/Groovy and am trying to find a node in a an xml file; I've figured out how to iterate over all of them, but I want to exit the loop when the target node is found. I've read that instead of using "each", use "find", but the find examples I've seen are conditions. Right now the logic I have is going to iterate through the whole file without exiting. The code is below:

  records.children().each {domain ->    println "domain_name: " + domain.@domain_name    if (domain.@domain_name == targetDomain) {          println "target domain matched: " + domain.@domain_name              domain.children().each {misc_field ->            println "field_name: " + misc_field.@field_name      println "field_type: " + misc_field.@field_type      println "field_value: " + misc_field           }    }   } 
like image 706
Jack BeNimble Avatar asked Nov 19 '09 22:11

Jack BeNimble


People also ask

How do you break groovy on each loop?

Nope, you can't abort an "each" without throwing an exception. You likely want a classic loop if you want the break to abort under a particular condition. Alternatively, you could use a "find" closure instead of an each and return true when you would have done a break.


2 Answers

You cannot do it elegantly. You might see some people suggest throwing an Exception, but that's just plain ugly.

Here's some mailing list discussion on using each vs. for, and a couple people say that for is preferred because of each's inability to break from the iteration.

Your best bet is probably to change over to a for loop and iterate:

for(def domain : records.children()) { // this may need some tweaking depending on types     // do stuff     if(condition) {         break;     } } 

Either that, or like you said, maybe use find or findAll to find the element you're looking for (the following code is paraphrased, I don't have time yet to test it out):

def result = records.children().find { domain -> domain.@domain_name == targetDomain } result.children().each {     // print stuff } 

Related SO questions:

  • best-pattern-for-simulating-continue-in-groovy-closure
  • is-it-possible-to-break-out-of-closure-in-groovy
like image 136
Rob Hruska Avatar answered Sep 20 '22 21:09

Rob Hruska


Replace each loop with any or find closure.

def list = [1, 2, 3, 4, 5] list.any { element ->     if (element == 2)         return // continue      println element      if (element == 3)         true // break } 

Output

1 3 
like image 34
Michal Z m u d a Avatar answered Sep 20 '22 21:09

Michal Z m u d a