我需要一种简便的方法来组合groovy中的地图,结果与+略有不同

时间:2014-09-19 20:41:10

标签: groovy map

注意:这可以作为方法调用或操作员覆盖非常容易,我正在寻找一个内在的单行解决方案,我不必在库中随身携带。

组合(添加)地图时,会得到如下结果:

println [a:1,c:3] + [a:2]
// prints {a=2, c=3}

我似乎更需要结果:

{a=[1, 2], c=[3]}

换句话说,它结合了地图中相同键的所有值。

是否有一个操作员或简单的函数调用来执行此操作,因为自己这样做似乎总是打破我的步伐。似乎*运算符可能很好地完成了这一点,但它并没有。

有一种简单的方法吗?

2 个答案:

答案 0 :(得分:3)

另一种选择(将其添加到地图上的*运算符)

def a = [ a:1, c:10 ]
def b = [ b:1, a:3 ]

Map.metaClass.multiply = { Map other ->
    (delegate.keySet() + other.keySet()).inject( [:].withDefault { [] } ) { m, v ->
        if (delegate[v] != null) { m[v] << delegate[v] }
        if (other[v] != null) { m[v] << other[v] }
        m
    }
}

assert a * b == [a:[1, 3], c:[10], b:[1]]

也提到了这一点,但现在已经很晚了,可能有更好,更短的方式

def a = [ a:1, c:10 ] 
def b = [ b:1, a:3 ]

[a,b]*.collect {k,v -> [(k):v]}
      .flatten()
      .groupBy { it.keySet()[0]}
      .inject([:].withDefault{[]}) {m,v->
          m << [(v.key):v.value[v.key]]
      }
  ​​

答案 1 :(得分:2)

我没有想到什么,所以我开始这样做:

m1 = [a:1, c:666]; m2 = [a:2, b:42]
result = [:].withDefault{[]}
[m1,m2].each{ it.each{ result[it.key] << it.value } }
assert result == [a:[1,2], b:[42], c:[666]]