如何在Groovy中迭代嵌套地图的所有值

rbo*_*boy 2 groovy

我有一个未知结构的嵌套映射,目标是遍历映射中的每个值,检查某个条件(例如null)的值,然后将其替换为其他值。如果地图结构已知,我可以看到如何做,但是这里的问题是它是未知的。

例如,这可以是传递的地图结构(或可以具有任意数量的嵌套地图):

?def map = [
          a:5,
          b:"r",
          c:[ a1:0, b1:null ],
          d:[ a2: [ a3:"", b3:99 ], b2:null ],
          ...
]
Run Code Online (Sandbox Code Playgroud)

通常对于一个简单的地图,可以使用this来更新值:

map.each { it.value == null ? it.value = "" : "" }
Run Code Online (Sandbox Code Playgroud)

但是,对于嵌套地图结构,此方法将不起作用。

有没有一种有效的方法来遍历未知地图的所有嵌套值以调查和更新这些值?

cfr*_*ick 5

您可以对每一个进行运行,但是随后需要递归获取地图。例如看deNull

def deNull(def root) {
    root.each{
        if (it.value instanceof Map) {
            deNull(it.value)
        } else if (it.value==null) {
            it.value = ""
        }
    }
}

def map = [
    a:5,
    b:"r",
    c:[ a1:0, b1:null ],
    d:[ a2: [ a3:"", b3:99 ], b2:null ],
]
println(map.tap{ deNull it }.inspect())
// => ['a':5, 'b':'r', 'c':['a1':0, 'b1':''], 'd':['a2':['a3':'', 'b3':99], 'b2':'']]
Run Code Online (Sandbox Code Playgroud)

对于正确的方法,我还将传递一个“做什么”的闭包,而不是在这里仅处理“ de-null-ing”(这使该可重用性)并命名postwalkMap或类似名称。