Reputation: 28599
i need to convert plain map with environment variables
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"
to a nested maps that in json looks like this:
{
"idx": {
"host": "192.168.99.100",
"port": {
"https": "9447"
}
},
"esb": {
"host": "192.168.99.100",
"port": {
"https": "8245",
"http": "8282"
}
}
}
below it the code that actually do this but i'd like to minimize/simplify it...
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()
Upvotes: 0
Views: 45
Reputation: 37063
If your initial keys would have the right order (IDX_PORT_HTTPS
instead of
PORT_IDX_HTTPS
), you could just set them with a "nested" put. So you could
split on _
like you do already and swap(0,1)
the first two elements. Then
use that as path to set the value into a map. E.g.:
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)
})
Upvotes: 1
Reputation: 24498
This question is border-line subjective/opinionated, but given the problem as stated, why not just do this:
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()
Upvotes: 1