Вот лучшее из того, что я придумал до сих пор:
def walk(v, Closure transform ) {
switch (v) {
case null:
return null
case Map:
return v.collectEntries { mk, mv -> [ transform(mk), walk(mv, transform) ] }
case List:
return v.collect { lv -> walk(lv, transform) }
default:
return transform(v)
}
}
, который с учетом приведенных выше примеров данных, может применяться как:
def engine = new groovy.text.SimpleTemplateEngine()
def subs = ['VARIABLE': 'REPLACED']
def newconfig = walk(config) { v ->
switch (v) {
case String:
return engine.createTemplate(v).make(subs)
default:
return v
}
}
Это зависит от умного Groovyswitch
заявление.Он не расширяемый, вы не можете просто подключить свои собственные обработчики типов, но это так просто, что вам не нужно.По умолчанию он выполняет гибридное копирование, создавая новые экземпляры List
s и Map
s, но сохраняя ссылки на исходные скалярные или несопоставленные типы.Это может быть сделано для глубокого копирования, в соответствии со следующими примерами преобразования идентичности:
// Identity transform, shallow copy scalars
assert (config == (walk(config) { v -> v.clone() }))
// Identity transform, deep copy scalars where possible
assert (config == (walk(config) {
v ->
try {
return v.clone()
} catch (java.lang.CloneNotSupportedException ex) {
return v
}
}))
Мысли?Лучшие способы?