Dictionary Groovy列表:按元素列表分组

Dictionary Groovy列表:按元素列表分组,dictionary,groovy,collections,Dictionary,Groovy,Collections,我基本上想对地图进行分组,我必须按汽车和颜色进行分组,并对其价格进行求和,如果任何一组价格大于25,则按汽车、颜色和电机对结果进行分组,并乘以求和*3,第一部分完成,但第二组的结果是: def row1 = ["car":'A',"color":'B',"motor":'C', "price": 12] def row2 = ["car":'A',"color":'B',"motor":'C', "price": 12] def row3 = ["car":'A',"color":'B',"mo

我基本上想对地图进行分组,我必须按汽车和颜色进行分组,并对其价格进行求和,如果任何一组价格大于25,则按汽车、颜色和电机对结果进行分组,并乘以求和*3,第一部分完成,但第二组的结果是:

def row1 = ["car":'A',"color":'B',"motor":'C', "price": 12]
def row2 = ["car":'A',"color":'B',"motor":'C', "price": 12]
def row3 = ["car":'A',"color":'B',"motor":'D', "price": 2]
def row4 = ["car":'B',"color":'B',"motor":'D', "price": 13]
def arrayRows = []
arrayRows.add(row1)
arrayRows.add(row2)
arrayRows.add(row3)
arrayRows.add(row4)
println(arrayRows) //[[car:A, color:B, motor:C, price:12], [car:A, color:B, motor:C, price:12], [car:A, color:B, motor:D, price:2], [car:B, color:B, motor:D, price:13]]
def groups = arrayRows.groupBy {row -> [Car:row.car, Color:row.color] }.collect{k , v ->
    [
        car:k.Car,
        color:k.Color,
        motor:v.motor,
        price:v.collect { it.price }.sum()
    ]
}
println(groups) //[[car:A, color:B, motor:[C, C, D], price:26], [car:B, color:B, motor:[D], price:13]]
for(group in groups){
    if (group.price > 25){ //26>25
        println group //[car:A, color:B, motor:[C, C, D], price:26]
        //def groupByCarColorMotor = arrayRows.groupBy {[Car: group.car, Color: group.color, Motor:?]} | Must group by car, color and motor, and multiply * 3 it's price but since motor is an array, I'm not sure how to do so, I've tried groupBy { row -> group.it.motor} etc
    }
}

如果我有: [汽车:A,颜色:B,马达:[C,C,D] 我应该分组如下: [汽车:A,颜色:B,电机:C] 及 [汽车:A,颜色:B,电机:D]

预期输出应为: [[“汽车”:'A'、“颜色”:'B'、“电机”:'C'、“价格”:72、[“汽车”:'A'、“颜色”:'B'、“电机”:'D'、“价格”:6]]

编辑; 我几乎做到了,问题是我得到了一系列的地图,而且你可能也会得到它背后的想法

def arrayRows = [ 
        ["car":'A',"color":'B',"motor":'C', "price": 12],
        ["car":'A',"color":'B',"motor":'C', "price": 12],
        ["car":'A',"color":'B',"motor":'D', "price": 2],
        ["car":'B',"color":'B',"motor":'D', "price": 13]
        ]

println(arrayRows) //[[car:A, color:B, motor:C, price:12], [car:A, color:B, motor:C, price:12], [car:A, color:B, motor:D, price:2], [car:B, color:B, motor:D, price:13]]
def groups = arrayRows.groupBy {row -> [Car:row.car, Color:row.color] }.collect{k , v ->
    [
            car:k.Car,
            color:k.Color,
            price:v.collect { it.price }.sum()
    ]
}.findAll{it.price > 25}

def groupByCarColor = []
for (group in groups){
    groupByCarColor.add(arrayRows.findAll{ row -> row.car == group.car && row.color == group.color}.groupBy {row -> [Car:group.car, Color:group.color, Motor:row.motor] }.collect{k , v ->
        [
                car:k.Car,
                color:k.Color,
                motor:k.Motor,
                price:v.collect { it.price }.sum()*3
        ]
    })
}

输出:[[car:A,color:B,motor:C,price:72],[car:A,color:B,motor:D,price:6]]

为您的家庭作业准备一些简单的东西:

def arrayRows = [
["car":'A',"color":'B',"motor":'C', "price": 13],
["car":'A',"color":'B',"motor":'D', "price": 14],
["car":'B',"color":'B',"motor":'D', "price": 13],
]

List out = arrayRows.groupBy{ [ car:it.car, color:it.color ] }.inject( [] ){ List res, k, v ->
  if( 25 < v*.price.sum() ) v.each{ res << ( it + [ price:it.price * 3 ] ) }
  res
}

assert out.toString() == '[[car:A, color:B, motor:C, price:39], [car:A, color:B, motor:D, price:42]]'
def arrayRows=[
[“汽车:'A',“颜色:'B',“电机:'C',“价格:'13],
[“汽车”:'A',“颜色”:'B',“电机”:'D',“价格”:14],
[“汽车”:“B”、“颜色”:“B”、“电机”:“D”、“价格”:13],
]
List out=arrayRows.groupBy{[car:it.car,color:it.color]}.inject([]){List res,k,v->

如果(25
def arrayRows = [
["car":'A',"color":'B',"motor":'C', "price": 13],
["car":'A',"color":'B',"motor":'D', "price": 14],
["car":'B',"color":'B',"motor":'D', "price": 13],
]

List out = arrayRows.groupBy{ [ car:it.car, color:it.color ] }.inject( [] ){ List res, k, v ->
  if( 25 < v*.price.sum() ) v.each{ res << ( it + [ price:it.price * 3 ] ) }
  res
}

assert out.toString() == '[[car:A, color:B, motor:C, price:39], [car:A, color:B, motor:D, price:42]]'
def arrayRows=[
[“汽车:'A',“颜色:'B',“电机:'C',“价格:'13],
[“汽车”:'A',“颜色”:'B',“电机”:'D',“价格”:14],
[“汽车”:“B”、“颜色”:“B”、“电机”:“D”、“价格”:13],
]
List out=arrayRows.groupBy{[car:it.car,color:it.color]}.inject([]){List res,k,v->

如果(25
def arrayRows = [ 
    [car:'A', motor:'C', color:'B',price: 12],
    [car:'A', motor:'C', color:'B',price: 12],
    [car:'A', motor:'D', color:'B',price:  2],
    [car:'B', motor:'D', color:'B',price: 13],
]


def output = arrayRows.inject([:].withDefault{ 0 }){ acc, row -> // group by the triplet and sum up the price
    acc[row.subMap(['car','motor','color'])]+=row.price; acc
}.groupBy{ k, _ -> // group by the filter criteria tuple
    k.subMap(['car','color'])
}.findAll{ _, v -> // eliminate the tuple-groups where price is to low
    v.values().sum() > 25
}.collectMany{ _, vs -> // reshape the data
    vs.collect{ k, v ->
        k + [price: v * 3]
    }
}

assert output==[[car:"A", motor:"C", color:"B", price:72], [car:"A", motor:"D", color:"B", price:6]]

您的目标是通过一个三元组来查找组,但您希望筛选出谓词在子组上失败的组

def arrayRows = [ 
    [car:'A', motor:'C', color:'B',price: 12],
    [car:'A', motor:'C', color:'B',price: 12],
    [car:'A', motor:'D', color:'B',price:  2],
    [car:'B', motor:'D', color:'B',price: 13],
]


def output = arrayRows.inject([:].withDefault{ 0 }){ acc, row -> // group by the triplet and sum up the price
    acc[row.subMap(['car','motor','color'])]+=row.price; acc
}.groupBy{ k, _ -> // group by the filter criteria tuple
    k.subMap(['car','color'])
}.findAll{ _, v -> // eliminate the tuple-groups where price is to low
    v.values().sum() > 25
}.collectMany{ _, vs -> // reshape the data
    vs.collect{ k, v ->
        k + [price: v * 3]
    }
}

assert output==[[car:"A", motor:"C", color:"B", price:72], [car:"A", motor:"D", color:"B", price:6]]

尽管输出是正确的,但想象一下以下情况:[“汽车”:“A”,“颜色”:“B”,“电机”:“C”,“价格”:13],“汽车”:“A”,“颜色”:“B”,“电机”:“C”,“价格”:14]输出应该是:[[汽车:A,颜色:B,电机:C,价格:81]](13+14*3)因此,我将按汽车和颜色分组,将条件设为25,然后再按汽车、颜色和马达对第一个groupBy的结果进行分组。不确定这是否是唯一的答案。我更改了示例虽然输出是正确的,但想象以下情况:[“汽车”:“A”,“颜色”:“B”,“马达”:“C”,“价格”:13”,“汽车”:“A”,“颜色”:“B”,“马达”:“C”,“价格”:14]输出应为:[[汽车:A,颜色:B,马达:C,价格:81]](13+14*3)所以我将用汽车和颜色分组,使条件为25,再分组由汽车、颜色和马达的第一组的结果。不确定这是否是唯一的答案通过。我改变了一个小组的结果是什么,没有超过25的价格总和?@ cFRICE我们不应该考虑这些为第二个GR。oup部分。如果有非,则输出应为空数组。这将发生在[“汽车”:'B'、“颜色”:'B'、“电机”:'D'、“价格”:13]上,因为所有汽车和颜色(B,B)的价格之和不要总和超过25。一个团体的结果是什么,没有超过25的价格总和?@ CfFICE我们不应该考虑第二组的一部分。如果没有,输出应该是一个空的数组。这会发生在[车]:“B”,“颜色”:“B”,“马达”:“将”,“价格”:13,因为所有汽车的价格和颜色(B,B)的总和。求和不要超过25。基本上就是这样,注释也非常有用,命名我想要实现的目标也很有用!谢谢!我还有一个问题,我不确定是否应该编辑这个问题或创建另一个问题,如果我在地图中有另一个参数,我怎么做,例如:[car:'A',motor:'C',color:'B',price:15,parameter:“hi”],[car:'A',motor:'C',color:'B',hi”],[car:'A',motor:'C',color:'B',price:26,parameter:[“hi”,“hi”]在我看来,第一次注入是对groupBy的替代,以避免解释的问题。您可以替换第一步(这是一个groupBy和求和的组合)和一个groupBy,然后从那里开始工作。但是另一个参数回避了如何在分组步骤中聚合它的问题。如果它只是一个常量,你可以在上面管道的第一步中添加它(当价格被添加时)基本上就是这样,评论也非常有用,我想实现的目标命名也很有用!谢谢!我还有一个问题,我不确定是否应该编辑这个问题或创建另一个问题,如果我在地图中有另一个参数,我怎么做,例如:[车:'a',马达:'C',颜色:'B',价格:15,参数:“hi”],[car:'A',motor:'C',color:'B',price:11,参数:“hi”]。最终结果将是:[car:'A',motor:'C',color:'B',price:26,参数:[“hi”,“hi”]]在我看来,第一次注入是对groupBy的替换,以避免所解释的问题。您可以替换第一步(这是groupBy和求和的组合)只需要一个groupBy,然后从那里开始工作。但是另一个参数回避了如何在分组步骤中聚合它的问题。如果它只是一个常量,您可以在上述管道的第一步中添加它(当添加价格时)