Zapętlić mapę w Groovy?

175

Mam bardzo proste zadanie, które próbuję wykonać w Groovy, ale wydaje mi się, że nie mogę go uruchomić. Po prostu próbuję przelecieć przez obiekt mapy w groovy i wydrukować klucz i wartość, ale ten kod nie działa.

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

Próbuję uzyskać dane wyjściowe, aby wyglądały następująco:

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

Czy mógłby ktoś wyjaśnić, jak to zrobić?

Kevin
źródło
Jak widzieliście w odpowiedziach, problem polega na tym, że iteracja po mapie daje zbiór „wpisów”, przy założeniu, że da wam klucze i będziecie szukać wartości. Jeśli chcesz to zrobić w ten sposób, wykonaj iterację po map.keySet (), a reszta będzie działać zgodnie z oczekiwaniami.
Bill K
Powinno działać, jeśli używasz s.key& s.valuew swoim kodzie wewnątrz pętli for.
inblueswithu

Odpowiedzi:

328

Całkiem proste z zamknięciem:

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

map.each{ k, v -> println "${k}:${v}" }
Jacek
źródło
2
Z ciekawości, gdzie jest to udokumentowane w dokumentach w języku Groovy ( nie sądzę! )? Myślę, że zastanawiam się, z perspektywy nowicjuszy Groovy'ego, skąd o tym wiedziałeś?
smeeb
10
@smeeb: wszystko jest dobrze udokumentowane, spójrz tutaj: groovy-lang.org/groovy-dev-kit.html#_iterating_on_maps
Jack
101

Alternatywnie możesz użyć forpętli, jak pokazano w 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
*/

Jedną z zalet używania forpętli w przeciwieństwie do eachzamknięcia jest łatwiejsze debugowanie, ponieważ nie można trafić w punkt przerwania wewnątrz eachzamknięcia (podczas korzystania z Netbeans).

ubiquibacon
źródło
Używam GGTS 3.2 i rutynowo ustawiam punkty przerwania w zamknięciach (w tym zamknięciach „każdego”). Problem polega na tym, że użycie klawisza F6 do przejścia przez zamknięcie, ponieważ przejdzie przez całą sprawę. Technicznie rzecz biorąc, możesz uderzyć F5 kilka razy i ostatecznie tam trafić, ale punkt przerwania jest szybszy.
Filip
Zaktualizowana odpowiedź. Używam Netbeans i jego debugowanie Groovy / Grails jest poniżej par.
ubiquibacon
4
Dodatkowo możesz wyrwać pętlę for, a nie wejść .each.
Alexander Suraphel
1
@AlexanderSuraphel masz rację, której nie możesz użyć, breakaby wyjść each, ale możesz użyćreturn
ubiquibacon
7
@ubiquibacon no, nie możesz. returnjest analogiczne do continuenie break.
Alexander Suraphel
20

W przypadku korzystania z pętli for wartością s jest element Map.Entry, co oznacza, że ​​klucz można pobrać z s.key, a wartość z s.value

sbglasius
źródło
5
Dzięki za wyjaśnienie, dlaczego kod OP nie działa
dj18
15

Inna opcja:

def map = ['a':1, 'b':2, 'c':3]
map.each{
  println it.key +" "+ it.value
}
Pablo Pazos
źródło