Groovy 简化将普通贴图转换为嵌套贴图的代码

Groovy 简化将普通贴图转换为嵌套贴图的代码,groovy,Groovy,我需要用环境变量转换平面图 HOST_IDX :"192.168.99.100", PORT_IDX_HTTPS:"9447", HOST_ESB :"192.168.99.100", PORT_ESB_HTTPS:"8245", PORT_ESB_HTTP :"8282", OTHER :"foo" 到json中的嵌套映射如下所示: { "idx": { "host": "192.16

我需要用环境变量转换平面图

    HOST_IDX      :"192.168.99.100",
    PORT_IDX_HTTPS:"9447",
    HOST_ESB      :"192.168.99.100",
    PORT_ESB_HTTPS:"8245",
    PORT_ESB_HTTP :"8282",
    OTHER         :"foo"
到json中的嵌套映射如下所示:

{
    "idx": {
        "host": "192.168.99.100",
        "port": {
            "https": "9447"
        }
    },
    "esb": {
        "host": "192.168.99.100",
        "port": {
            "https": "8245",
            "http": "8282"
        }
    }
}
下面是实际执行此操作的代码,但我希望将其最小化/简化

def env=[
    HOST_IDX:"192.168.99.100",
    PORT_IDX_HTTPS:"9447",
    HOST_ESB:"192.168.99.100",
    PORT_ESB_HTTPS:"8245",
    PORT_ESB_HTTP:"8282",
    OTHER:"foo"
]

def x=env
    .collectEntries{[it.key.toLowerCase().split('_'),it.value]}
    .findAll{it.key[0] in ['host','port']}
    .groupBy( {it.key[1]}, {it.key[0]} )
    .collectEntries{[
            it.key, it.value.collectEntries{[
                it.key, it.key=='host' ? it.value.entrySet()[0].value : it.value.collectEntries{[
                    it.key[-1], it.value
                ]}
            ]}
        ]}

println new groovy.json.JsonBuilder(x).toPrettyString()

这个问题是主观的/固执己见的,但鉴于上述问题,为什么不这样做:

def x = [
    "idx" : ["host" : env["HOST_IDX"],
             "port" : ["https" : env["PORT_IDX_HTTPS"]]],
    "esb" : ["host" : env["HOST_IDX"],
             "port" : ["https" : env["PORT_ESB_HTTPS"],
                       "http" : env["PORT_ESB_HTTP"]]]
]

println new groovy.json.JsonBuilder(x).toPrettyString()

这个问题是主观的/固执己见的,但鉴于上述问题,为什么不这样做:

def x = [
    "idx" : ["host" : env["HOST_IDX"],
             "port" : ["https" : env["PORT_IDX_HTTPS"]]],
    "esb" : ["host" : env["HOST_IDX"],
             "port" : ["https" : env["PORT_ESB_HTTPS"],
                       "http" : env["PORT_ESB_HTTP"]]]
]

println new groovy.json.JsonBuilder(x).toPrettyString()

如果您的初始密钥顺序正确(
IDX\u PORT\u HTTPS
而不是
PORT\u IDX\u HTTPS
),您可以使用“嵌套”put设置它们。所以你可以 在
\uuu
上进行拆分,就像您已经做的那样,并
交换(0,1)
前两个元素。然后 使用该路径将值设置到地图中。例如:

def env=[
    HOST_IDX:"192.168.99.100",
    PORT_IDX_HTTPS:"9447",
    HOST_ESB:"192.168.99.100",
    PORT_ESB_HTTPS:"8245",
    PORT_ESB_HTTP:"8282",
]

// simplified nested put
def assocIn(m, path, v) {
    path.dropRight(1).inject(m){p,k->p.get(k,[:])}.put(path.last(), v) 
    return m
}

// split the keys and swap the first two elements to get a path to use
// for a nested put
println(env.inject([:]){ m, it ->
    assocIn(m, it.key.toLowerCase().split("_").swap(0,1), it.value)
})

如果您的初始密钥顺序正确(
IDX\u PORT\u HTTPS
而不是
PORT\u IDX\u HTTPS
),您可以使用“嵌套”put设置它们。所以你可以 在
\uuu
上进行拆分,就像您已经做的那样,并
交换(0,1)
前两个元素。然后 使用该路径将值设置到地图中。例如:

def env=[
    HOST_IDX:"192.168.99.100",
    PORT_IDX_HTTPS:"9447",
    HOST_ESB:"192.168.99.100",
    PORT_ESB_HTTPS:"8245",
    PORT_ESB_HTTP:"8282",
]

// simplified nested put
def assocIn(m, path, v) {
    path.dropRight(1).inject(m){p,k->p.get(k,[:])}.put(path.last(), v) 
    return m
}

// split the keys and swap the first two elements to get a path to use
// for a nested put
println(env.inject([:]){ m, it ->
    assocIn(m, it.key.toLowerCase().split("_").swap(0,1), it.value)
})