Groovy 2.4.7三级Map结构重构异常求助
三级Map结构转换问题(Groovy 2.4.7)
需求说明
需要将如下三级Map结构:
[ 1: [ Par1: [ Podpar1: [s: 'str1', time: 16], Podpar2: [s: 'str2', time: 16] ], Par2: [ Podpar1: [s: 0, time: 16], Podpar2: [s: 0, time: 16] ] ], 2: [ Par1: [ Podpar1: [s: 'str3', time: 16], Podpar2: [s: 'str4', time: 16] ], Par2: [ Podpar1: [s: 0, time: 16], Podpar2: [s: 0, time: 16] ] ] ]
转换为层级调整后的结构:
[ 1: [ Podpar1: [ Par1: [s: 'str1', time: 16], Par2: [s: 0, time: 16] ], Podpar2: [ Par1: [s: 'str2', time: 16], Par2: [s: 0, time: 16] ] ], 2: [ Podpar1: [ Par1: [s: 'str3', time: 16], Par2: [s: 0, time: 16] ], Podpar2: [ Par1: [s: 'str4', time: 16], Par2: [s: 0, time: 16] ] ] ]
问题重现
尝试使用以下代码实现转换:
def res = [ "1" : [ "Par1" : [ "Podpar1" : [ "s" : "str" , "time" : 16 ] , "Podpar2" : [ "s" : "str" , "time" : 16 ]], "Par2" : ["Podpar1" : ["s" : 0 ,"time" : 16] , "Podpar2" : ["s" : 0 , "time" : 16 ]], "2" : ["Par1" : ["Podpar1" : ["s" : "str1" ,"time" : 16] ,"Podpar2" : ["s" : "str1" ,"time" : 16]]], "Par2" : ["Podpar1" : ["s" : 0 ,"time" : 16 ] ,"Podpar2" : ["s" : 0 ,"time" : 16]]]] def reconfMap = [:] res.each { k, v -> reconfMap[k] = [:] def temppar = [:] def temppodpar = [:] v.each { park, parv -> parv.each { podpark, podparv -> temppar[park]=podparv temppodpar[podpark]= temppar reconfMap[k] = temppodpar } } }
运行后出现元素覆盖问题,得到错误结果:
[1:[Podpar1:[Par1:[s:str2, time:16], Par2:[s:0, time:16]], Podpar2:[Par1:[s:str2, time:16], Par2:[s:0, time:16]]], 2:[Podpar1:[Par1:[s:str4, time:16], Par2:[s:0, time:16]], Podpar2:[Par1:[s:str4, time:16], Par2:[s:0, time:16]]]]
期望的正确结果为:
[1:[Podpar1:[Par1:[s:str1, time:16], Par2:[s:0, time:16]], Podpar2:[Par1:[s:str2, time:16], Par2:[s:0, time:16]]], 2:[Podpar1:[Par1:[s:str3, time:16], Par2:[s:0, time:16]], Podpar2:[Par1:[s:str4, time:16], Par2:[s:0, time:16]]]]
问题原因
代码中temppar是同一个Map引用,每次循环修改temppar[park]都会改变这个Map的内容,所有Podpar对应的temppar指向的都是同一个对象。当循环结束时,temppar中存储的是最后一次循环的Par值,导致所有Podpar的Par1都被覆盖为最后一个值。
解决代码
以下是修正后的代码,通过为每个Podpar创建独立的子Map避免引用覆盖:
def originalMap = [ 1: [ Par1: [ Podpar1: [s: 'str1', time: 16], Podpar2: [s: 'str2', time: 16] ], Par2: [ Podpar1: [s: 0, time: 16], Podpar2: [s: 0, time: 16] ] ], 2: [ Par1: [ Podpar1: [s: 'str3', time: 16], Podpar2: [s: 'str4', time: 16] ], Par2: [ Podpar1: [s: 0, time: 16], Podpar2: [s: 0, time: 16] ] ] ] def transformedMap = [:] originalMap.each { topKey, parMap -> transformedMap[topKey] = [:] // 收集当前顶层Key下所有Podpar的键,确保不遗漏 def allPodparKeys = parMap.values().collect { it.keySet() }.flatten().unique() allPodparKeys.each { podparKey -> // 为每个Podpar创建独立的Map,存储对应的Par值 def podparEntry = [:] parMap.each { parKey, podparMap -> podparEntry[parKey] = podparMap[podparKey] } transformedMap[topKey][podparKey] = podparEntry } } println transformedMap
代码逻辑说明
- 遍历每个顶层Key,初始化对应的空Map用于存储转换后的数据
- 收集当前顶层Key下所有Podpar的键,确保不会遗漏任何Podpar项
- 对每个Podpar键,创建独立的子Map,遍历所有Par项,将对应Podpar的值存入该子Map
- 将构建好的Podpar子Map存入转换后的顶层Map中,保证每个Podpar对应的Par数据都是独立的,不会出现覆盖问题
内容的提问来源于stack exchange,提问作者dobtyimolodec
相关产品推荐
相关产品推荐

