2011-02-25 138 views
5

我需要填充一張地圖,這樣:列表,Grails中映射值

  • 關鍵是字符串
  • 值是字符串列表

的過程是去通過具有兩個文本字段的表格中的所有記錄:「參數」和「值」。 「參數」不是唯一的,有很多重複。所以我打算做的是:

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

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

任何線索?

感謝

回答

9

有一個恕我直言有點簡單的方式通過在Groovy 1.7引入了「withDefault」這樣做:

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

另外,使用Groovy 1.8+,您可以執行以下所有操作'all.groupBy {it.parameter} .collectEntries {k,v - > [(k):v * .value]}'這可能更簡單一些:-) – 2011-02-28 13:51:28

+0

此外,在Groovy 1.8之前,您可以這樣做:'all.groupBy {it.parameter} .inject([:]){地圖,val - > map << [(val.key):val.value * .value]}' – 2011-03-01 13:00:08

+0

但我認爲上面更具可讀性。 – 2011-03-01 13:58:33

6

可以使用Map.groupBy方法,這將集合分成地圖基於在封閉的組經由。這裏有一個完整的例子,這也要求收集,使每個參數指向剛纔值:

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比我的回答好得多。我將代碼編碼爲java ...將工作壓下來,但不是很酷.... – hvgotcodes 2011-02-25 22:34:36