2017-10-18 68 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()