2010-09-24 11 views
17

Est-ce que groovy supporte n'importe quel type de notation d'itérateur imbriquée?Comment faites-vous les itérateurs imbriqués dans groovy?

Dans l'exemple ci-dessous, je souhaite obtenir la valeur projectName, qui provient de l'itérateur externe, dans mon itérateur interne. Est-ce possible sans stocker dans une variable? Dans mon exemple, je reçois une erreur de runtuime que « projet » ne se trouve pas

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

Répondre

17

Il se sent comme cela devrait fonctionner:

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

En outre, vous pouvez faire référence à la fermeture externe en utilisant la variable owner

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

Cependant, je ne vois pas une raison pour itérer sur les rôles si tout ce que vous semblez faire est de créer de nouvelles instances de la classe Rôle. Peut-être quelque chose comme cela sera plus 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 et sélectionné pour répondre réellement à la question que j'ai posée – Derek

+0

Vous pouvez également spécifier la classe de votre itérateur nommé si votre IDE ne peut pas le comprendre, par exemple: 'it.myprojects.project.each {Project project -> .. Parfois, j'aime faire ça pour l'auto-complétion et autres. On peut dire que cela pollue votre code inutilement pour le bénéfice de votre IDE, mais il est là si vous le voulez. –

0
it.projectList.each {...} 

?

et ceci: http://groovy.codehaus.org/Looping.

Vous bouclez sur la liste, pas sur la chose dans la liste. Semble de votre code, vous êtes en boucle sur la chose dans la liste.

+0

err, thats mon mauvais sur les syntax..i suis tirant en fait ce à partir d'un fichier XML et j'avais quelques balises appelé « Projectlist » et « rolelist » de sorte que la liste de mots est juste une coïncidence – Derek

+0

édité le code maintenant donc il n'y a pas de confusion – Derek

+0

@derek y at-il encore un problème? Lancez-le dans votre débogueur préféré et voyez quel est le projet ... aussi, j'ai remarqué que le premier jeton dans votre code est 'ça', donc il semble qu'il y a des choses qui sortent du code que vous avez posté que vous pourriez vouloir partager. – hvgotcodes

26

Ces variables it sont pas itérateurs, ils sont closure paramètres. Le nom it n'est pas court pour "itérateur", il signifie littéralement "it", utilisé comme nom par défaut pour les fermetures à un seul paramètre. Cependant, vous pouvez utiliser des noms explicites (et donc différents imbriqués) comme ceci:

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

En fait, je vous conseille de ne pas utiliser la méthode each du tout et l'utilisation des boucles réelles à la place:

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

Cette est préférable car les fermetures rendent le code beaucoup plus difficile à déboguer, et potentiellement plus lent. Et dans ce cas, il n'y a vraiment aucun avantage à utiliser des fermetures de toute façon.

+0

ah - c'est confus. Le code fonctionne définitivement si vous continuez à réutiliser "it" de manière imbriquée. Il m'est apparu que quelque chose de drôle se passait quand j'ai essayé de faire une référence à la précédente – Derek

+2

@Derek: On dirait que vous faites une programmation de culte de la cargaison, c'est-à-dire essayer d'utiliser la syntaxe sans comprendre ça veut dire. Pas étonnant que vous soyez confus. Vous avez vraiment besoin de lire sur les fermetures jusqu'à ce que vous compreniez que "each" est une méthode, pas un mot-clé de langue, le code dans les accolades est une fermeture passée en paramètre à la méthode, et le "it" est le paramètre implicite de la fermeture quand elle est appelée par chaque méthode. –

+1

Je ne vois pas pourquoi une boucle explicite serait meilleure que l'utilisation de chaque méthode - il s'agit plus d'un cas de style personnel et de préférence. – mfloryan