Passar pelo mapa no Groovy?

175

Tenho uma tarefa muito simples que estou tentando executar no Groovy, mas não consigo fazê-la funcionar. Estou apenas tentando percorrer um objeto de mapa no groovy e imprimir a chave e o valor, mas esse código não funciona.

// 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]
}

Estou tentando fazer com que a saída fique assim:

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

Alguém poderia por favor elaborar sobre como fazer isso?

Kevin
fonte
Como você viu nas respostas, o problema é que a iteração sobre um mapa fornece uma coleção de "Entradas", você estava assumindo que ele forneceria as chaves e procuraria os valores. Se você quiser fazer dessa maneira, itere sobre map.keySet () e o restante funcionará conforme o esperado.
Bill K
Deverá funcionar se você usar s.key& s.valueno seu código dentro do loop.
inblueswithu

Respostas:

328

Muito simples com um fechamento:

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

map.each{ k, v -> println "${k}:${v}" }
Jack
fonte
2
Por curiosidade, onde isso está documentado nos documentos da linguagem Groovy ( eu não acho que seja! )? Acho que estou pensando, do ponto de vista dos novatos do Groovy, como você sabia disso?
smeeb
10
@smeeb: tudo está bem documentado, dê uma olhada aqui: groovy-lang.org/groovy-dev-kit.html#_iterating_on_maps
Jack
101

Como alternativa, você pode usar um forloop, como mostrado no Groovy Docs :

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
*/

Um benefício do uso de um forloop em oposição a um eachfechamento é a depuração mais fácil, pois você não pode atingir um ponto de interrupção dentro de um eachfechamento (ao usar o Netbeans).

ubiquibacon
fonte
Uso o GGTS 3.2 e defino rotineiramente pontos de interrupção nos fechamentos (incluindo os fechamentos "cada"). O problema é usar o F6 para passar por um fechamento, pois ele abordará a coisa toda. Tecnicamente, você pode pressionar F5 várias vezes e eventualmente acabar lá, mas um ponto de interrupção é mais rápido.
Philip
Resposta atualizada. Estou usando o Netbeans e sua depuração do Groovy / Grails está abaixo da média.
Ubiquibacon
4
Além disso, você pode quebrar um loop for e não entrar .each.
Alexander Suraphel
1
@AlexanderSuraphel você está correto que você não pode usar breakpara sair each, mas você pode usarreturn
ubiquibacon
7
@ubiquibacon não, você não pode. returné análogo a continuenão break.
Alexander Suraphel
20

Ao usar o loop for, o valor de s é um elemento Map.Entry, o que significa que você pode obter a chave de s.key e o valor de s.value

sbglasius
fonte
5
Obrigado por explicar por que o código do OP não funciona
dj18
15

Outra opção:

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