2010-09-24 27 views
17

¿Soporta groovy cualquier tipo de notación de iterador anidado?¿Cómo se hacen los iteradores anidados en Groovy?

En el siguiente ejemplo, quiero conseguir de alguna manera el valor projectName, que venía del iterador exterior, en mi iterador interno. ¿Es esto posible sin almacenar en una variable? En mi ejemplo, me sale un error que runtuime "proyecto" no se encuentra

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? 
    } 
} 

Respuesta

17

Se siente como esto debería funcionar:

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

Además, se puede hacer referencia al cierre exterior utilizando la variable de owner

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

Sin embargo, no veo una razón para iterar sobre los roles si todo lo que parece hacer es crear nuevas instancias de la clase Rol. Tal vez algo como esto será más simple:

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

+1 y seleccionado para responder realmente la pregunta que hice – Derek

+0

También puede especificar la clase de su iterador con nombre si su IDE no puede resolverlo, por ejemplo: 'it.myprojects.project.each {Project project -> .. .' A veces me gusta hacer esto para autocompletar y tal. Podría decirse que esto contamina su código innecesariamente para el beneficio de su IDE, pero está ahí si lo desea. –

0
it.projectList.each {...} 

?

y esto: http://groovy.codehaus.org/Looping.

Usted bucle en la lista, no en la hora de la lista. Parece que de su código está haciendo un bucle en la cosa en la lista.

+0

err, esa es mi mal en los syntax..i en realidad estoy tirando esto desde un archivo XML y que había algunas etiquetas llamado "projectlist" y "listaPapeles" por lo que la lista de palabras es sólo una coincidencia – Derek

+0

editado el código ahora para que no haya confusión – Derek

+0

@derek es todavía un problema? Enciéndalo en su depurador favorito y vea qué proyecto es ... también, me di cuenta de que el primer token en su código es 'eso', por lo que parece que hay cosas que están sucediendo fuera del código que publicó y que tal vez desee compartir. – hvgotcodes

26

Las variables it son no iteradores, son closure parámetros. El nombre it no es la abreviatura de "iterador", literalmente significa "it", utilizado como nombre predeterminado para cierres de un solo parámetro. Sin embargo, puede utilizar nombres explícitos (y por lo tanto diferentes anidados) de esta manera:

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

En realidad, me aconsejan no utilizar el método each en absoluto y el uso de bucles reales en su lugar:

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) 
    } 
} 

Este es mejor porque los cierres hacen que el código sea mucho más difícil de depurar, y también potencialmente más lento. Y en este caso, no hay ninguna ventaja en el uso de cierres de todos modos.

+0

ah - que es confuso. El código definitivamente funciona si sigues reutilizando "it" de forma anidada. Sólo se me hizo evidente que había algo raro pasa cuando traté de hacer una copia de referencia a la anterior – Derek

+2

@Derek: Suena como que está haciendo la programación de cargo y de culto, es decir, tratar de utilizar la sintaxis sin entender lo significa. No es de extrañar que estés confundido. Que realmente necesita para leer sobre los cierres hasta que entiende que "cada uno" es un método, no una palabra clave del lenguaje, el código entre llaves es un cierre pasado como parámetro al método, y el "ello" es el parámetro implícito de el cierre cuando es llamado por cada método. –

+1

No veo por qué un bucle explícito sería mejor que usar cada método, es más un caso de estilo personal y preferencia. – mfloryan

Cuestiones relacionadas