> 使用 groovy 构建,groovy,closures"/>

首页 > 解决方案 > 合并地图的优雅方式> 使用 groovy 构建

问题描述

我有一个嵌套地图结构:

Map<String, List<String>> case_pool = [
  dev : [
    funcA : ['devCaseA'] ,
    funcB : ['devCaseB'] ,
    funcC : ['devCaseC']
  ],
  'dev/funcA' : [
    funcA : ['performanceCaseA']
  ],
  'dev/funcA/feature' : [
    funcA : ['performanceCaseA', 'featureCase']
  ],
  staging : [
   funcB : ['stgCaseB'] ,
   funcC : ['stgCaseC']
  ]
]

并希望得到结果,when branch.contains(case_pool.key),然后合并案例列表。IE:

String branch = 'dev/funcA/feature-1.0'

// will final get result of " 'dev' + 'dev/funcA' + 'dev/funcA/feature' ":
result: 
[
  funcA: [ "devCaseA", "performanceCaseA", "featureCase" ],
  funcB: [ "devCaseB" ],
  funcC: [ "devCaseC" ]
]

首先我使用循环:

String branch = 'dev/funcA/feature-1.0'
def result = [:].withDefault { [] as Set }
case_pool.keySet().each {
  if ( branch.contains(it) ) {
    case_pool.get(it).each { k, v ->
      result[k].addAll(v)
    }
  }
}
println 'result: ' + result

其次,我正在使用闭包:


String branch = 'dev/funcA/feature-1.0'
def result = [:].withDefault { [] as Set }
case_pool.findAll{ k, v -> branch.contains(k) }.collectMany{ k, v -> v.collect{ c, l ->
    result[c].addAll(l)
}}
println 'result: ' + result

但是,我不喜欢.collectMany{ k, v -> v.collect{ c, l -> }}. 有没有更好的解决方案?(即:使用groupBy,或其他东西)

顺便说一句,我试过了collectEntries,结果最终的 List 将全部替换:

String branch = 'dev/funcA/feature-1.0'
println case_pool.findAll{ k, v -> branch.contains(k) }.collect{ k, v -> v}.collectEntries{it}

result: [funcA:[performanceCaseA, featureCase], funcB:[devCaseB], funcC:[devCaseC]]

决赛funcA : ['performanceCaseA', 'featureCase']取代了所有funcA: []

标签: groovyclosures

解决方案


正如cfrick所说, aninject在这里更好,即:

def result = case_pool.inject([:].withDefault { [] as Set }) { result, key, value ->
    if (branch.contains(key)) {
        value.each { k, v ->
            result[k] += v
        }
    }
    result
}

推荐阅读