Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Leaf nodes in a nested map

Tags:

groovy

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] }
like image 864
zoran119 Avatar asked Jan 30 '26 04:01

zoran119


1 Answers

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

like image 75
tim_yates Avatar answered Feb 02 '26 00:02

tim_yates



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!