Liste

2011-02-25 13 views
5

ben böylece Harita doldurmak gerekir:Liste

  • Anahtar String
  • değer

süreç gitmektir Strings bir listesi olduğunu İki metin alanına sahip bir tablodaki tüm kayıtlar aracılığıyla: "parametre" ve "değer". "Parametre" benzersiz değildir ve çok sayıda kopyası vardır. Bunu yapmak istediğim şey şu:

def all = MyTable.findAll() 
def mymap = [:] 

all.each { 
    // add to mymap the element "it.value" to the list that has "it.parameter" as key 
} 

Herhangi bir ipucu?

Teşekkür

cevap

9

:

all = [ 
    [parameter: 'foo', value: 'aaa'], 
    [parameter: 'foo', value: 'bbb'], 
    [parameter: 'bar', value: 'ccc'], 
    [parameter: 'baz', value: 'ddd'] 
] 

def myMap = [:].withDefault { [] } 
all.each { 
    myMap[it.parameter] << it.value 
} 

assert myMap.size() == 3 
assert myMap.foo == ['aaa','bbb'] 
assert myMap.bar == ['ccc'] 
assert myMap.baz == ['ddd'] 
+1

Bir arada, Groovy 1.8+ ile aşağıdakileri yapabilirsiniz: all.groupBy {it.parameter} .collectEntries {k, v -> [(k): v * .value]} 'yine daha basit olan :-) –

+0

Ayrıca, Groovy 1.8'den önce şunları yapabilirsiniz:' all.groupBy {it.parameter} .inject ([:]) { harita, val -> harita << [(val.key): val.value * .value]} ' –

+0

fakat yukarıdakilerin daha okunabilir olduğunu varsayalım. –

6

Sen kapatılması geçirilen dayalı grupların harita haline koleksiyon bölecek Map.groupBy yöntemini kullanabilirsiniz. Burada ayrıca her parametre noktasını sadece değerler yapmak ödemeli çağıran bir tam örnek var:

Groovy 1.7 tanıtılan 'withDefault' kullanarak bunu bir IMHO biraz daha basit bir yolu yoktur
all = [ 
    [parameter: 'foo', value: 'aaa'], 
    [parameter: 'foo', value: 'bbb'], 
    [parameter: 'bar', value: 'ccc'], 
    [parameter: 'baz', value: 'ddd'] 
] 
tmpMap = all.groupBy{it.parameter} 
myMap = [:].putAll(tmpMap.collect{k, v -> [k, v.value] as MapEntry}) 

assert myMap == [foo: ['aaa', 'bbb'], bar: ['ccc'], baz:['ddd']] 
+4

+1 Cevabımdan çok daha iyi. Ben java olarak groovy kodu ... iş alır, ama serin değil .... – hvgotcodes