首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用groovy对列表进行分组

如何使用groovy对列表进行分组
EN

Stack Overflow用户
提问于 2013-10-12 08:35:46
回答 5查看 7K关注 0票数 4

我有一个清单,我想分组按marketName和commodityName,按上市价格:。“泰拉”,“小麦”,1000.0 -“泰拉”是市场名称,“小麦”是商品名称,1000.0是价格

代码语言:javascript
复制
def marketCommodityGroup = [
                              ["Merkato", "Wheat", 1000.0],  
                              ["Shola", "Wheat", 1875.0],  
                              ["Merkato", "Barley", 5000.0],  
                              ["Merkato", "Wheat", 1000.0],  
                              ["Merkato", "Wheat", 1500.0] 
                           ] 

我希望产出如下:

代码语言:javascript
复制
[
   ["Merkato": ["Wheat" : [1000.0, 1000.0, 1500.0]]],
   ["Merkato": ["Barley": [5000.0]]],
   ["Shola": ["Wheat": [1875.0]]]
]
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-10-12 09:48:23

好吧,这里有一种方法。

代码语言:javascript
复制
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做最后的地图分配来得到精确的想要的形式

是的,它有点密集和神奇,但您总是可以移动闭包,以维护正确的,描述性的名称。

票数 8
EN

Stack Overflow用户

发布于 2013-10-12 18:21:13

编辑:现在返回地图列表,每个原始问题

在某种程度上受Vamsi Krishna的回答的影响,但是用链式的withDefault

代码语言:javascript
复制
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
票数 3
EN

Stack Overflow用户

发布于 2013-10-14 12:07:55

另一个版本只是为了好玩;-)

代码语言:javascript
复制
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]]]
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19332248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档