2017-10-18 63 views
0

我需要简单的地图转换与环境变量的代码简化普通的地图转换为嵌套地图

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() 

回答

1

如果您最初的钥匙将有正确的顺序(IDX_PORT_HTTPS而不是 PORT_IDX_HTTPS),你可以只设置它们具有“嵌套“放。所以你可以 拆分_像你已经和swap(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) 
}) 
+0

非常感谢。现在我知道一个新的方法:'inject' :) – daggett

1

这个问题是border-line subje莫如/坚持己见,但表示鉴于这个问题,为什么不这样做:

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()