groovy 嵌套地图更新值而不检查值的类型
groovy nested map update value without checking type of value
我有两张地图,
def configmap = [ "env" :["required": ["team" : "k", "test": "sample"], "optional" : ["anotherkey" : ""]]]
def valuesReplacementMap=[ "env.required.team":"s","env.required.test":"new", "env.optional.anotherkey":"newvalue" ]
valuesReplacementMap
具有指向 configmap
中的键的路径以及需要更新的新值。
我需要将 configmap
中的值更新为 valuesReplacementMap
中给定的值
这是我的代码,有效
def m = [ "env" :["required": ["team" : "k", "test": "sample"], "optional" : ["anotherkey" : ""]]]
def valuesReplacementMap=[ "env.required.team":"s",
"env.required.test":"new",
"env.optional.anotherkey":"newvalue" ]
def copyofOrigMap
valuesReplacementMap.each{ key, value->
copyofOrigMap = m
key.tokenize(".").inject{ attr, val ->
if(copyofOrigMap[attr][val] instanceof java.lang.String ){
copyofOrigMap[attr][val] = value
}else
copyofOrigMap = copyofOrigMap[attr]
val
}
}
我的问题是
- 有没有一种方法可以避免检查
instanceof java.lang.String
,我这样做是为了查看是否到达叶 node/key
- 有没有更简单的方法来实现这整个功能
我查看了一些较早发布的问题,但没有找到任何优化方法
Updating value in a map while iterating the map groovy
解决此问题的一种方法是 Eval.me
。以下代码:
def m = [ "env" :["required": ["team" : "k", "test": "sample"], "optional" : ["anotherkey" : ""]]]
def valuesReplacementMap=[ "env.required.team":"s",
"env.required.test":"new",
"env.optional.anotherkey":"newvalue" ]
valuesReplacementMap.each { k, v ->
Eval.me('m', m, "m.${k} = '${v}'")
}
m.each { k, v ->
println "$k -> $v"
}
执行结果为:
─➤ groovy solution.groovy
env -> [required:[team:s, test:new], optional:[anotherkey:newvalue]]
─➤
(在 Groovy 版本:3.0.5 JVM:11.0.8 供应商:Amazon.com Inc. OS:Linux)
Eval.me
方法的第一个参数 'm'
param 告诉 eval 我们希望字符串表达式中的值绑定到名称 m
,第二个参数是值本身。第三个参数是要计算的表达式。
可能有比 eval 更优雅的东西,但它非常简洁,可以为您提供所需的结果。
还应注意,这仅适用于字符串值,如果任何键或值来自用户输入,从安全角度来看使用 Eval 可能是危险的。
编辑可能具有更好的安全隐患
作为替代方案,您可以这样做:
def m = [ "env" :["required": ["team" : "k", "test": "sample"], "optional" : ["anotherkey" : ""]]]
def valuesReplacementMap=[ "env.required.team":"s",
"env.required.test":"new",
"env.optional.anotherkey":"newvalue" ]
valuesReplacementMap.each { k, v ->
def tokens = k.tokenize('.')
def last = tokens.init().inject(m) { a, t -> a[t] }
last[tokens.last()] = v
}
m.each { k, v ->
println "$k -> $v"
}
产生的输出与上面的 Eval.me
示例相同。
我有两张地图,
def configmap = [ "env" :["required": ["team" : "k", "test": "sample"], "optional" : ["anotherkey" : ""]]]
def valuesReplacementMap=[ "env.required.team":"s","env.required.test":"new", "env.optional.anotherkey":"newvalue" ]
valuesReplacementMap
具有指向 configmap
中的键的路径以及需要更新的新值。
我需要将 configmap
中的值更新为 valuesReplacementMap
这是我的代码,有效
def m = [ "env" :["required": ["team" : "k", "test": "sample"], "optional" : ["anotherkey" : ""]]]
def valuesReplacementMap=[ "env.required.team":"s",
"env.required.test":"new",
"env.optional.anotherkey":"newvalue" ]
def copyofOrigMap
valuesReplacementMap.each{ key, value->
copyofOrigMap = m
key.tokenize(".").inject{ attr, val ->
if(copyofOrigMap[attr][val] instanceof java.lang.String ){
copyofOrigMap[attr][val] = value
}else
copyofOrigMap = copyofOrigMap[attr]
val
}
}
我的问题是
- 有没有一种方法可以避免检查
instanceof java.lang.String
,我这样做是为了查看是否到达叶 node/key - 有没有更简单的方法来实现这整个功能
我查看了一些较早发布的问题,但没有找到任何优化方法
Updating value in a map while iterating the map groovy
解决此问题的一种方法是 Eval.me
。以下代码:
def m = [ "env" :["required": ["team" : "k", "test": "sample"], "optional" : ["anotherkey" : ""]]]
def valuesReplacementMap=[ "env.required.team":"s",
"env.required.test":"new",
"env.optional.anotherkey":"newvalue" ]
valuesReplacementMap.each { k, v ->
Eval.me('m', m, "m.${k} = '${v}'")
}
m.each { k, v ->
println "$k -> $v"
}
执行结果为:
─➤ groovy solution.groovy
env -> [required:[team:s, test:new], optional:[anotherkey:newvalue]]
─➤
(在 Groovy 版本:3.0.5 JVM:11.0.8 供应商:Amazon.com Inc. OS:Linux)
Eval.me
方法的第一个参数 'm'
param 告诉 eval 我们希望字符串表达式中的值绑定到名称 m
,第二个参数是值本身。第三个参数是要计算的表达式。
可能有比 eval 更优雅的东西,但它非常简洁,可以为您提供所需的结果。
还应注意,这仅适用于字符串值,如果任何键或值来自用户输入,从安全角度来看使用 Eval 可能是危险的。
编辑可能具有更好的安全隐患
作为替代方案,您可以这样做:
def m = [ "env" :["required": ["team" : "k", "test": "sample"], "optional" : ["anotherkey" : ""]]]
def valuesReplacementMap=[ "env.required.team":"s",
"env.required.test":"new",
"env.optional.anotherkey":"newvalue" ]
valuesReplacementMap.each { k, v ->
def tokens = k.tokenize('.')
def last = tokens.init().inject(m) { a, t -> a[t] }
last[tokens.last()] = v
}
m.each { k, v ->
println "$k -> $v"
}
产生的输出与上面的 Eval.me
示例相同。