如果值是给定文本,我想有条件地删除集合,或者为null。
下面是一个简单的例子:
def map1 = [
1: "#NULL",
2: [
2.1: "some value",
2.2: "some value"
]]
assert map1.dropWhile { key, value ->
value.equals("#NULL") || value == null
} == [2: [2.1: "some value", 2.2: "some value"]]
但是,这种下降虽然不处理子级别键和值。下面的一个将无法断言:
def map2 = [
1: "#NULL",
2: [
2.1: "#NULL",
2.2: "some value"
]]
assert map2.dropWhile { key, value ->
value.equals("#NULL") || value == null
} == [2: [2.2: "some value"]]
有办法做到这一点吗?
<小时/> 蒂姆的回答后更新了 现在,下面的脚本将运行良好:
def defaultMap = [
1: "some value",
2: [
2.1: "some value",
2.2: "some value",
2.3: [
"2.3.1": "some value",
"2.3.2": " some value"
]
]
]
def replacementMap = [2: [2.4: "some other value"]]
assert defaultMap.collectEntries(replacementMap) { mapKey, mapValue ->
[mapKey, replacementMap.containsKey(mapKey) ? replacementMap[mapKey] : mapValue] // Remove default key and value pairs, if they are present in the replacement map.
// New key and value pairs in the replacement map will be preserved
}.collectEntries { mapKey, mapValue ->
switch (mapValue) {
case Map:
return [mapKey, { -> mapValue.collectEntries owner }()]
case '#NULL': // Remove key, if the value is also TEXT #NULL
return [:]
default:
[mapKey, mapValue]
}
} == [2: [2.4: 'some other value'], 1: 'some value']
但是,如果我想要使子图无效,但是将所有其他子图保持在同一级别,则它无法正常工作:
def defaultMap = [
1: "some value",
2: [
2.1: "some value",
2.2: "some value",
2.3: [
"2.3.1": "some value",
"2.3.2": " some value"
]
]
]
def replacementMap = [2.3: '#NULL']
assert defaultMap.collectEntries(replacementMap) { mapKey, mapValue ->
[mapKey, replacementMap.containsKey(mapKey) ? replacementMap[mapKey] : mapValue] // Remove default key and value pairs, if they are present in the replacement map.
// New key and value pairs in the replacement map will be preserved
}.collectEntries { mapKey, mapValue ->
switch (mapValue) {
case Map:
return [mapKey, { -> mapValue.collectEntries owner }()]
case '#NULL': // Remove key, if the value is also TEXT #NULL
return [:]
default:
[mapKey, mapValue]
}
} == [1:'some value', 2:[2.1:'some value', 2.2:'some value', 2.3:null]]
答案 0 :(得分:2)
你可以写一个简单的递归地图漫步者:
def map2 = [
'1': "#NULL",
'2': [
'2.1': "#NULL",
'2.2': "some value"
]
]
def result = map2.collectEntries { name, value ->
switch(value) {
case Map:
return [name, { -> value.collectEntries owner }()]
case '#NULL':
return [:]
default:
[name, value]
}
}
assert result == ['2':['2.2':'some value']]
答案 1 :(得分:0)
您只需要使用递归方法:
def map2 = [
1: "#NULL",
2: [
2.1: "#NULL",
2.2: "some value"
]
]
def dropRecursive(Map m) {
m.dropWhile { k, v ->
if (v in Map) {
m[k] = dropRecursive(v)
return false
} else {
v == null || '#NULL'.equals(v)
}
}
}
assert dropRecursive(map2) == [2: [2.2: "some value"]]
在处理return false
时需要使用Map
,因为结果会投影到boolean
表达式。由于groovy中非空Map
为true
,因此也会将其删除,这是不需要的。尝试使用和不使用它进行实验。