Je suis nouveau sur Grails/Groovy et j'essaie de trouver un nœud dans un fichier xml; J'ai compris comment itérer sur chacun d'eux, mais je veux quitter la boucle lorsque le nœud cible est trouvé. J'ai lu qu'au lieu d'utiliser "chacun", utilisez "find", mais les exemples de recherche que j'ai vus sont des conditions. En ce moment, la logique que j'ai va parcourir tout le fichier sans quitter. Le code est ci-dessous:
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
}
}
}
Vous ne pouvez pas le faire avec élégance. Vous pourriez voir certaines personnes suggérer de lever une exception, mais c'est juste tout simplement laid .
Voici quelques discussion sur la liste de diffusion sur l'utilisation de each
contre for
, et quelques personnes disent que for
est préférable en raison de each
l'incapacité de rompre avec l'itération.
Votre meilleur pari est probablement de passer à une boucle for
et d'itérer:
for(def domain : records.children()) { // this may need some tweaking depending on types
// do stuff
if(condition) {
break;
}
}
Soit cela, ou comme vous l'avez dit, utilisez peut-être find ou findAll pour trouver l'élément que vous recherchez (le code suivant est paraphrasé, je n'ai pas encore le temps pour le tester):
def result = records.children().find { domain -> domain.@domain_name == targetDomain }
result.children().each {
// print stuff
}
Questions connexes SO:
Remplacez chaque boucle par tout ou find fermeture.
def list = [1, 2, 3, 4, 5]
list.any { element ->
if (element == 2)
return // continue
println element
if (element == 3)
true // break
}
Production
1
3
En ce qui concerne la rupture de chaque boucle, voir: est-il possible de "casser" une fermeture groovy
Fondamentalement, vous devez lancer une exception et l'attraper. Le mot-clé "break" n'est autorisé qu'à l'intérieur des boucles non "fermetures" itérées (vraiment des blocs de code).
Vous pouvez utiliser n'importe quel code complexe avec "find", assurez-vous simplement que la fonction que vous appelez renvoie un booléen. Par exemple:
Boolean test(val) {
println "Testing $val"
return val == 1
}
def found = [3,4,5,1,6,3].find { test(it) }
println "Found $found"
Je pense que cela devrait aussi marcher, s'arrêter au premier match.
def result = records.children().find { domain ->
if (domain.@domain_name == targetDomain) {
// Do stuff
...
return true
} else {
return false
}
}