【发布时间】:2020-10-09 11:35:08
【问题描述】:
我有一个嵌套地图结构:
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']
]
]
想要得到结果,当branch.contains(case_pool.key),然后合并案例列表。
即:
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,结果发现最终列表将全部替换:
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: []
【问题讨论】:
-
对我来说最令人困惑的部分是,您正在嵌套 collectMany/collect ,然后在里面做一个副作用并丢弃结果。我会改用
inject。类似于result = case_bool.findAll{,,,}.inject([:].withDefault...}) { r, kv -> kv.values().each { c, l -> r[c].addAll(l) }; r } -
感谢@cfrick。我试过你的方式
println case_pool.findAll{ k, v -> branch.contains(k) }.inject([:]) { r, kv -> kv.values().each { c, l -> r[c].addAll(l) }; r },并得到问题:No signature of method: java.util.LinkedHashMap$Entry.values() is applicable for argument types: () values: []