zoran119
zoran119

Reputation: 11307

Leaf nodes in a nested map

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

Answers (1)

tim_yates
tim_yates

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

Related Questions