groovy - 合并地图的优雅方式> 使用 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: []
解决方案
正如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
}
推荐阅读
- java - VPL 中的编译错误,但 Intellij 中没有(Java,大学作业)
- scipy - Scipy - Skimage - slic 不适用于灰度图像
- python - 如何在热图中添加自定义刻度?
- sql - Postgresql 查询将列转置为行
- git - 如何对 GitLab 的网络文件夹进行源代码控制?
- gnuplot - gnuplot:圆圈之间的箭头
- python - 箭头键通过 Gtk.FlowBox.select_child() 忽略选择
- javascript - 函数的预期值
- c++ - 在构造期间初始化 const 成员
- python-3.x - 按一定顺序连接 2 个列表