Reputation: 11307
Given a nested map like this:
def map = [group: [group_name: 'test', group_color: 'red']]
is there a way to turn it into this:
['group-group_name': 'test', 'group-group_color': 'red']
The map could have any level of nesting.
Further explanation: If the map is thought of as a tree, I want the resulting map to have all the leaf values as its values, and each key should be an 'absolute' key built using all the keys from the top of the tree to the leaf node (in the example above all the keys are joined using -
).
This is what I'd like (doesn't work of course):
def newMap = map.findAll { it.isLeaf() }.collect { [it.absoluteKeyPath: it.value] }
Upvotes: 3
Views: 708
Reputation: 171144
I believe this should do it:
def map = [ cheese: 'cheddar',
group: [ group_name: 'test',
group_color: 'red',
deep:[ bool:'yes' ] ] ]
def compress( Map m, String prefix = '' ) {
prefix = prefix ? "$prefix-" : ''
m.collectEntries { k, v ->
if( v instanceof Map ) compress( v, "$prefix$k" )
else [ ("$prefix$k".toString()): v ]
}
}
assert compress( map ) == [ 'cheese':'cheddar',
'group-group_name':'test',
'group-group_color':'red',
'group-deep-bool':'yes' ]
Of course, you need to take care as map keys can already contain -
chars, so you might lose data if one is named the same as a path to a leaf
Upvotes: 3