2010-09-24 9 views
17

Groovy supporta qualsiasi tipo di notazione iteratore annidata?Come si fanno gli iteratori nidificati in groovy?

Nell'esempio seguente, voglio in qualche modo ottenere il valore projectName, che proviene dall'iteratore esterno, nel mio iteratore interno. È possibile senza memorizzare una variabile? Nel mio esempio, ottengo un errore runtuime che "progetto" non si trova

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

risposta

17

Ci si sente come questo dovrebbe funzionare:

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

Inoltre, è possibile fare riferimento alla chiusura esterna utilizzando la variabile owner

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

Tuttavia, non vedo una ragione per iterare su ruoli se tutto ciò che sembra fare è creare nuove istanze della classe Role. Forse qualcosa di simile sarà più semplice:

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

+1 e selezionato per rispondere effettivamente alla domanda che ho chiesto – Derek

+0

Puoi anche specificare la classe del tuo iteratore con nome se il tuo IDE non riesce a capirlo, ad esempio: 'it.myprojects.project.each {Progetto progetto -> .. . A volte mi piace farlo per l'autocompletamento e così via. Probabilmente, questo inquina il tuo codice inutilmente per il beneficio dell'IDE, ma è lì se lo vuoi. –

0
it.projectList.each {...} 

?

e questo: http://groovy.codehaus.org/Looping.

Si loop sulla lista, non sulla cosa nella lista. Sembra dal tuo codice che stai collegando la cosa nella lista.

+0

err, questo è il mio male sulle syntax..i sono in realtà tirando questo da un file XML e avevo alcuni tag chiamato "projectlist" e "rolelist", così l'elenco di parole è solo una coincidenza – Derek

+0

modificato il codice ora quindi non c'è confusione – Derek

+0

@derek c'è ancora un problema? Accendi il tuo debugger preferito e vedi quale progetto è ... Inoltre, ho notato che il primo token nel tuo codice è "it", quindi sembra che ci sia qualcosa che sta fuori dal codice che hai postato che potresti voler Condividere. – hvgotcodes

26

Quelle variabili it sono non iteratori, sono parametri closure. Il nome it non è l'abbreviazione di "iteratore", significa letteralmente "it", utilizzato come nome predefinito per le chiusure a parametro singolo. Tuttavia, è possibile utilizzare i nomi espliciti (e quindi diverse annidati) in questo modo:

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

In realtà, vorrei consigliare di non usare il metodo each a tutti e utilizzare i cicli reali invece:

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

Questo è meglio perché le chiusure rendono il codice molto più difficile da eseguire il debug e anche potenzialmente più lento. E in questo caso, non c'è alcun vantaggio nell'utilizzo delle chiusure comunque.

+0

ah - questo è fonte di confusione. Il codice funziona sicuramente se continui a riutilizzarlo "in modo annidato". Mi è apparso chiaro che c'era qualcosa di strano quando ho provato a fare un riferimento alla precedente – Derek

+2

@Derek: Sembra che tu stia programmando un carico-setta, cioè cercando di usare la sintassi senza capire cosa significa. Non mi sorprende che tu sia confuso. Hai davvero bisogno di leggere le chiusure fino a capire che "ogni" è un metodo, non una parola chiave della lingua, il codice nelle parentesi graffe è una chiusura passata come parametro al metodo, e "it" è il parametro implicito di la chiusura quando viene chiamata da ciascun metodo. –

+1

Non vedo perché un ciclo esplicito sarebbe meglio dell'utilizzo di ciascun metodo - è più un caso di stile personale e preferenza. – mfloryan

Problemi correlati