Groovy通过多个属性进行分组的方式只有一个级别

Groovy通过多个属性进行分组的方式只有一个级别,groovy,Groovy,我想按3个属性分组,但不希望每个属性都是它自己的嵌套数组。我想要的是: def values=[ [day:1,month:1,year:1], [day:1,month:1,year:1], [day:2,month:1,year:1], [day:2,month:2,year:1] ]; /*...some code to group by DAY, MONTH, AND YEAR ..desired result is that item

我想按3个属性分组,但不希望每个属性都是它自己的嵌套数组。我想要的是:

 def values=[
     [day:1,month:1,year:1],
     [day:1,month:1,year:1],
     [day:2,month:1,year:1],
     [day:2,month:2,year:1]
 ];

 /*...some code to group by DAY, MONTH, AND YEAR

 ..desired result is that items with the same day, 
  month, and year end up in a one level deep subarray
 */

  [
    [[day:1,month:1,year:1],[day:1,month:1,year:1]],  
    [[day:2,month:1,year:1]] ,
    [[day:2,month:2,year:1]] 
  ];

使用带有多个闭包的groupBy()方法,我可以将每个分组属性作为自己的嵌套数组,如[year[month[day[]]],这不是我需要的。

考虑以下使用
inject
来构建一个键为相应组的映射,和值是所需的列表:

编辑:根据注释更新地图键的结构)

def值=[
[日:1,月:1,年:1],
[日:1,月:1,年:1],
[日:2,月:1,年:1],
[日期:2,月份:2,年份:1]
];
def groupMap=[:]。默认值为{key->[]}
def result=values.inject(groupMap){val,m->

val[“${m.'day'}:${m.'month'}:${m.'year'}”]您希望采用groupBy函数来完成所需的工作。在本例中,地图中已经有了您要对其进行分组的标识。因此,这就足以满足您所需的结果:

def values=[
    [day:1,month:1,year:1],
    [day:1,month:1,year:1],
    [day:2,month:1,year:1],
    [day:2,month:2,year:1],
]

// just the identity
println values.groupBy().values()
// => [[[day:1, month:1, year:1], [day:1, month:1, year:1]], [[day:2, month:1, year:1]], [[day:2, month:2, year:1]]]
如果您的地图中确实有更多的值,您可以使用
子地图
将其分组到一个级别:

// submap only the needed keys (in case there is more in `values` than just your identity
println values.groupBy{ it.subMap(["year","month","day"]) }.values()
// => [[[day:1, month:1, year:1], [day:1, month:1, year:1]], [[day:2, month:1, year:1]], [[day:2, month:2, year:1]]]

在挑剔方面:这些是您得到的嵌套映射。

调用.groupBy({…})并后跟.values()也会导致相同的结果。此外,请确保仔细检查用于分组的“键”模式。此示例使用一个简单字符串(足以显示概念),但1月11日和11月1日将无法区分(如果输入值真的像问题状态的简单整数)re:不可区分的键。很好的观点。我已经更新了映射的键结构,使它稍微更健壮。
// submap only the needed keys (in case there is more in `values` than just your identity
println values.groupBy{ it.subMap(["year","month","day"]) }.values()
// => [[[day:1, month:1, year:1], [day:1, month:1, year:1]], [[day:2, month:1, year:1]], [[day:2, month:2, year:1]]]