转换Groovy地图

时间:2018-05-23 10:08:01

标签: groovy

这是我的地图

    predicate sorted(input:array?<int>)
    requires input!=null;
    requires input.Length>0;
    reads input;
    {
        forall i,j::0<=i<j<input.Length ==> input[i]==1 || input[i]==input[j] || input[j]==2
    }

    method swap(input: array?<int>, n:int, m:int)
    modifies input;
    requires input!=null;
    requires input.Length>0;
    requires 0<=n<input.Length && 0<=m<input.Length
    {
        var tmp : int := input[n];
        input[n] := input[m];
        input[m] := tmp;
    }

我想对类似的值进行分组并得到:

[a: 1, b: 1, c: 2, d: 2, e: 1, f: 2]

我的最大努力是

[1: [a, b, e], 2: [c, d, f]]

什么是groov'ier?

2 个答案:

答案 0 :(得分:1)

以下代码:

def result = [a: 1, b: 1, c: 2, d: 2, e: 1, f: 2].inject([:].withDefault {[]}) { a, k, v ->
 a[v] << k 
 a
}

println result

打印:

[1:[a, b, e], 2:[c, d, f]]

这使用了与其他语言中的foldLeft或reduce相似的groovy Map.inject方法和groovy Map.withDefault方法,这样当您访问地图并找不到某个键时,默认值为返回空列表([])。

说明:

  • .inject( - 一次查看一个键值对
  • [:].withDefault {[]} - 从空地图开始,如果您访问不存在的密钥,将返回空列表
  • 每个键值对
  • ) { a, k, v -,使用初始地图a
  • 执行某些操作
  • a[v] << k - 具体而言,将传入密钥添加为密钥v下的地图中包含的列表中的元素(由withDefault返回)。
  • a - 返回修改后的地图,以便在下一次迭代中a中以{a, k, v ->的形式发送

答案 1 :(得分:0)

你已经拥有的已经是简单而优雅的。您仍然可以将其细化为

map.groupBy { it.value }.collectEntries { [it.key, it.value*.key ] } 

得到相同的结果。