web-dev-qa-db-fra.com

Groovy - comment quitter chaque boucle?

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

    }



   }
  }
24
Jack BeNimble

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:

42
Rob Hruska

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
5
Michal Z m u d a

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"
4
Alex Stoddard

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
    }
}
2
Paull