Groovy 嵌套映射中的叶节点

Groovy 嵌套映射中的叶节点,groovy,Groovy,给定这样的嵌套映射: def map = [group: [group_name: 'test', group_color: 'red']] 有没有办法把它变成这样: ['group-group_name': 'test', 'group-group_color': 'red'] 地图可以有任何级别的嵌套 进一步解释:如果将映射视为一棵树,我希望生成的映射将所有叶值都作为其值,并且每个键都应该是一个“绝对”键,使用从树顶部到叶节点的所有键构建(在上面的示例中,所有键都使用-连接) 这是我想要

给定这样的嵌套映射:

def map = [group: [group_name: 'test', group_color: 'red']]
有没有办法把它变成这样:

['group-group_name': 'test', 'group-group_color': 'red']
地图可以有任何级别的嵌套

进一步解释:如果将映射视为一棵树,我希望生成的映射将所有叶值都作为其值,并且每个键都应该是一个“绝对”键,使用从树顶部到叶节点的所有键构建(在上面的示例中,所有键都使用
-
连接)

这是我想要的(当然不行):


我认为这应该做到:

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' ]
当然,您需要小心,因为映射键可能已经包含
-
字符,因此如果其中一个被命名为与叶的路径相同,则可能会丢失数据

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' ]