Derek
Derek

Reputation: 11915

How do you do nested iterators in groovy?

Does groovy support any kind of nested iterator notation?

In the example below, I want to somehow get the projectName value, that came from the outer iterator, into my inner iterator. Is this possible without storing in a variable? In my example I get a runtuime error that "project" is not found

it.myprojects.project.each{
     println("Project name: " + it.projectName)
    it.myroles.role.each{
         Role role = new Role()
             role.setName(project.projectName)//how do I get projectName here without storting it in a variable in the outer loop?
    }
}

Upvotes: 21

Views: 27404

Answers (3)

mfloryan
mfloryan

Reputation: 7685

It feels like this should work:

it.myprojects.project.each{ project->
     println("Project name: " + project.projectName)
     it.myroles.role.each{
         Role role = new Role()
         role.setName(project.projectName)
    }
}

Also, you can reference the outer closure using the owner variable

it.myprojects.project.each{ 
     println("Project name: " + it.projectName)
     it.myroles.role.each{
         Role role = new Role()
             role.setName(owner.projectName)
    }
}

However, I don't see a reason for iterating over roles if all you seem to be doing is creating new instances of the Role class. Perhaps something like this will be simpler:

it.myprojects.project.each{ 
     println("Project name: " + it.projectName)
     it.myroles.role.size().times {
         Role role = new Role()
         role.setName(owner.projectName)
    }
}

Upvotes: 21

Michael Borgwardt
Michael Borgwardt

Reputation: 346240

Those it variables are not iterators, they are closure parameters. The name it is not short for "iterator", it literally means "it", used as a default name for single-parameter closures. However, you can use explicit (and thus different nested) names like this:

it.myprojects.project.each{ project ->
     println("Project name: " + project.projectName)
     project.myroles.role.each{ role->
         Role r= new Role()
         r.setName(project.projectName)
    }
}

Actually, I'd advise against using the each method at all and use real loops instead:

for(project in it.myprojects.project){
     println("Project name: " + project.projectName)
     for(role in project.myroles.role){
         Role r= new Role()
         r.setName(project.projectName)
    }
}

This is better because closures make the code much harder to debug, and also potentially slower. And in this case, there isn't really any advantage in using closures anyway.

Upvotes: 32

hvgotcodes
hvgotcodes

Reputation: 120138

 it.projectList.each {...}

?

and this: http://groovy.codehaus.org/Looping.

You loop on the list, not on the thing in the list. Seems from your code you are looping on the thing in the list.

Upvotes: 0

Related Questions