如何解决groovy嵌套地图更新值,而不检查值的类型
我有两张地图,
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","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
的方法,我正在这样做以查看是否达到了叶节点/密钥 - 有没有更简单的方法来实现全部功能
我经历了一些较早发布的问题,但是没有找到任何优化的方法
解决方法
解决此问题的一种方法是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.操作系统:Linux)
其中'm'
方法的第一个参数Eval.me
告诉eval我们想要在字符串表达式中绑定到名称m
的值,第二个参数是值本身。第三个参数是要求值的表达式。
可能有比eval更优雅的方法,但这很简洁,可以为您提供所需的结果。
还应注意,这仅适用于字符串值,并且从安全角度考虑,如果任何键或值来自用户输入,则使用Eval可能很危险。
修改可能会带来更好的安全隐患
您也可以执行以下操作:
def m = [ "env" :["required": ["team" : "k","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
示例相同。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。