我有一个清单,我想分组按marketName和commodityName,按上市价格:。“泰拉”,“小麦”,1000.0 -“泰拉”是市场名称,“小麦”是商品名称,1000.0是价格
def marketCommodityGroup = [
["Merkato", "Wheat", 1000.0],
["Shola", "Wheat", 1875.0],
["Merkato", "Barley", 5000.0],
["Merkato", "Wheat", 1000.0],
["Merkato", "Wheat", 1500.0]
] 我希望产出如下:
[
["Merkato": ["Wheat" : [1000.0, 1000.0, 1500.0]]],
["Merkato": ["Barley": [5000.0]]],
["Shola": ["Wheat": [1875.0]]]
]发布于 2013-10-12 09:48:23
好吧,这里有一种方法。
def mapped = marketCommodityGroup.groupBy {
[(it[0]) : it[1]]
}.collect { k,v ->
def grouping = k.find { true }
def prices = v.inject([]) { acc,val -> acc + val[2] }
[ (grouping.key) , [ (grouping.value) : prices ] ]
}.sort { left, right ->
right[0] <=> left[0]
}.collect {
[(it[0]) : it[1] ]
}groupBy按你说的做,它按市场名称和商品名称分组。collect创建了想要的结构,排除了最终的k:v关联:grouping是键映射拆分中唯一的条目,这样就可以将其重新排序到所需的形式。prices是用非常方便的inject完成的,这是Groovy在函数式语言中的fold left操作的等价物
sort是指按您指定的顺序翻转--必须询问实际逻辑是什么,所以您可能想要替换它。collect做最后的地图分配来得到精确的想要的形式是的,它有点密集和神奇,但您总是可以移动闭包,以维护正确的,描述性的名称。
发布于 2013-10-12 18:21:13
编辑:现在返回地图列表,每个原始问题
在某种程度上受Vamsi Krishna的回答的影响,但是用链式的withDefault:
def marketCommodityGroup = [
["Terra", "Wheat", 1000.0],
["Shola", "Wheat", 1875.0],
["Terra", "Barley", 5000.0],
["Terra", "Wheat", 1000.0],
["Terra", "Wheat", 1500.0]
]
def marketCommodityMap = [:].withDefault{ [:].withDefault{ [:].withDefault {[]} } }
// map looks like
// ["Terra-Wheat": ["Terra": ["Wheat": [1000.0 ...], "Barley": [5000.0] ]]]
// but we will discard the outer compound key
marketCommodityGroup.each { market, commodity, price ->
marketCommodityMap["${market}-${commodity}"][market][commodity] << price
}
def listOfMaps = marketCommodityMap.values()
println listOfMaps发布于 2013-10-14 12:07:55
另一个版本只是为了好玩;-)
def marketCommodityGroup = [ [ "Terra", "Wheat", 1000.0 ],
[ "Shola", "Wheat", 1875.0 ],
[ "Terra", "Barley", 5000.0 ],
[ "Terra", "Wheat", 1000.0 ],
[ "Terra", "Wheat", 1500.0 ] ]
def group( tree, data ) {
if( data.size() > 2 ) { group( tree."${data.head()}", data.tail() ) }
else {
if( !tree."${data.head()}" ) tree."${data.head()}" = []
tree."${data.head()}" << data[ -1 ]
}
}
def grouped = { [:].withDefault{ owner.call() } }()
marketCommodityGroup.each {
group( grouped, it )
}
assert grouped == ['Terra':['Wheat':[1000.0, 1000.0, 1500.0], 'Barley':[5000.0]],
'Shola':['Wheat':[1875.0]]]https://stackoverflow.com/questions/19332248
复制相似问题