Faire une boucle sur la carte à Groovy?

175

J'ai une tâche très simple que j'essaie de faire dans Groovy mais je n'arrive pas à la faire fonctionner. J'essaie juste de parcourir un objet de carte dans groovy et d'imprimer la clé et la valeur, mais ce code ne fonctionne pas.

// A simple map
def map = [
        iPhone : 'iWebOS',
        Android: '2.3.3',
        Nokia  : 'Symbian',
        Windows: 'WM8'
]

// Print the values
for (s in map) {
    println s + ": " + map[s]
}

J'essaie de faire en sorte que la sortie ressemble à ceci:

iPhone: iWebOS
Android: 2.3.3
Nokia: Symbian
Windows: WM8

Quelqu'un pourrait-il expliquer comment procéder?

Kevin
la source
Comme vous l'avez vu dans les réponses, le problème est que l'itération sur une carte vous donne une collection "d'entrées", vous supposiez que cela vous donnerait les clés et que vous rechercheriez les valeurs. Si vous vouliez le faire de cette façon, parcourez map.keySet () et le reste fonctionnera comme prévu.
Bill K
Cela devrait fonctionner si vous utilisez s.key& s.valuedans votre code à l'intérieur de la boucle for.
inblueswithu

Réponses:

328

Assez simple avec une fermeture:

def map = [
           'iPhone':'iWebOS',
           'Android':'2.3.3',
           'Nokia':'Symbian',
           'Windows':'WM8'
           ]

map.each{ k, v -> println "${k}:${v}" }
Jack
la source
2
Par curiosité, où est-ce documenté dans la documentation du langage Groovy ( je ne pense pas que ce soit le cas! )? Je suppose que je me demande, du point de vue des débutants Groovy, comment saviez-vous cela?
smeeb
10
@smeeb: tout est bien documenté, jetez un œil ici: groovy-lang.org/groovy-dev-kit.html#_iterating_on_maps
Jack
101

Vous pouvez également utiliser une forboucle comme indiqué dans la documentation Groovy :

def map = ['a':1, 'b':2, 'c':3]
for ( e in map ) {
    print "key = ${e.key}, value = ${e.value}"
}

/*
Result:
key = a, value = 1
key = b, value = 2
key = c, value = 3
*/

Un avantage de l'utilisation d'une forboucle par opposition à une eachfermeture est un débogage plus facile, car vous ne pouvez pas atteindre un point d'arrêt à l'intérieur d'une eachfermeture (lors de l'utilisation de Netbeans).

ubiquibacon
la source
J'utilise GGTS 3.2 et je règle régulièrement des points d'arrêt dans les fermetures (y compris les fermetures «chaque»). Le problème consiste à utiliser F6 pour passer à travers une fermeture, car cela couvrira l'ensemble. Techniquement, vous pouvez frapper F5 plusieurs fois et finir par y arriver, mais un point de rupture est plus rapide.
Philip
Réponse mise à jour. J'utilise Netbeans et son débogage de Groovy / Grails est médiocre.
ubiquibacon
4
De plus, vous pouvez sortir une boucle for et pas entrer .each.
Alexander Suraphel
1
@AlexanderSuraphel vous avez raison de ne pas pouvoir utiliser breakpour quitter each, mais vous pouvez utiliserreturn
ubiquibacon
7
@ubiquibacon non, vous ne pouvez pas. returnest analogue à continuenon break.
Alexander Suraphel
20

Lorsque vous utilisez la boucle for, la valeur de s est un élément Map.Entry, ce qui signifie que vous pouvez obtenir la clé de s.key et la valeur de s.value

sbglasius
la source
5
Merci d'avoir expliqué pourquoi le code de l'OP ne fonctionne pas
dj18
15

Une autre option:

def map = ['a':1, 'b':2, 'c':3]
map.each{
  println it.key +" "+ it.value
}
Pablo Pazos
la source