Groovy 中嵌套地图的默认值
Default values on nested maps in Groovy
我有一个 JSON 配置文件,我想用 groovy 读取
此文件具有“默认值”,以防因未添加特定配置而丢失一个键。
json
{
"presets": {
"default": "preset_default",
"Team1":{
"AppName1":{
"Component1": "preset_team1App1Comp1",
"default" : "preset_team1App1Default"
},
"AppName2":{
"Component1": "preset_team1App2Comp1",
"Component2": "preset_team1App2Comp2"
},
"default" : "preset_team1Default"
},
"Team2":{
"AppName1":{
"Component1": "preset_team2App1Comp1"
}
}
}
}
最 groovy 搜索值并回退到最外层“默认”键的方法是什么?
这是我的实现方式,但我不确定这是否可行:
if (presets[appTeam])
if (presets[appTeam][appName])
if (presets[appTeam][appName][compName])
this.preset = presets[appTeam][appName][compName]
else
this.preset = presets[appTeam][appName]['default']
else
this.preset = presets[appTeam]['default']
else
this.preset = presets['default']
提前致谢
一种方法是使用“注入”来遍历您的密钥,并跟踪看到的最新默认设置...像这样:
def value(Map presets, String... keys) {
keys.inject([pos: presets, result: presets.default]) { latest, current ->
def node = latest.pos[current]
if (node instanceof Map) {
[pos: node, result: node.default ?: latest.result]
} else if (node instanceof String) {
[pos: node, result: node]
} else if (node == null) {
[pos: node, result: latest.result]
} else {
throw new RuntimeException("No idea what to do with a ${node.class.simpleName}")
}
}.result
}
然后就可以了(用上面的例子)
// Defaults
assert value(presets, 'TeamUnknown', "AppName2", "Component14") == 'preset_default'
assert value(presets, 'Team1', "AppName2", "Component14") == 'preset_team1Default'
// Values
assert value(presets, 'Team1', "AppName2", "Component1") == 'preset_team1App2Comp1'
一个简单的通用递归会有所帮助:
def input = new groovy.json.JsonSlurper().parseText '''{
"presets": {
"default": "preset_default",
"Team1":{
"AppName1":{
"Component1": "preset_team1App1Comp1",
"default" : "preset_team1App1Default"
},
"AppName2":{
"Component1": "preset_team1App2Comp1",
"Component2": "preset_team1App2Comp2"
},
"default" : "preset_team1Default"
},
"Team2":{
"AppName1":{
"Component1": "preset_team2App1Comp1"
}
}
}
}'''
def findRecursive
findRecursive = { json, List keys, List defaults = [] ->
if( !json || ( json in String ) || !keys ) return json
if( json.default ) defaults << json.default
findRecursive json[ keys.remove( 0 ) ] ?: defaults.last(), keys, defaults
}
assert 'preset_team1App1Comp1' == findRecursive( input.presets, [ 'Team1', 'AppName1', 'Component1' ] )
assert 'preset_team2App1Comp1' == findRecursive( input.presets, [ 'Team2', 'AppName1', 'Component1' ] )
assert 'preset_team1Default' == findRecursive( input.presets, [ 'Team1', 'AppName3', 'Component1' ] )
assert 'preset_default' == findRecursive( input.presets, [ 'Team3' ] )
assert 'preset_default' == findRecursive( input.presets, [ 'Team2', 'AppName2', 'Component1' ] )
另一种方式
def value(presets, team, app, compt) {
def defkey = 'default'
return presets.get(team)?.get(app)?.get(compt) ?:
presets.get(team)?.get(app)?.get(defkey) ?:
presets.get(team)?.get(defkey) ?:
presets.get(defkey)
}
assert value(presets, 'TeamUnknown', "AppName2", "Component14") == 'preset_default'
assert value(presets, 'Team1', "AppName2", "Component14") == 'preset_team1Default'
assert value(presets, 'Team1', "AppName2", "Component1") == 'preset_team1App2Comp1'
我有一个 JSON 配置文件,我想用 groovy 读取 此文件具有“默认值”,以防因未添加特定配置而丢失一个键。
json
{
"presets": {
"default": "preset_default",
"Team1":{
"AppName1":{
"Component1": "preset_team1App1Comp1",
"default" : "preset_team1App1Default"
},
"AppName2":{
"Component1": "preset_team1App2Comp1",
"Component2": "preset_team1App2Comp2"
},
"default" : "preset_team1Default"
},
"Team2":{
"AppName1":{
"Component1": "preset_team2App1Comp1"
}
}
}
}
最 groovy 搜索值并回退到最外层“默认”键的方法是什么? 这是我的实现方式,但我不确定这是否可行:
if (presets[appTeam])
if (presets[appTeam][appName])
if (presets[appTeam][appName][compName])
this.preset = presets[appTeam][appName][compName]
else
this.preset = presets[appTeam][appName]['default']
else
this.preset = presets[appTeam]['default']
else
this.preset = presets['default']
提前致谢
一种方法是使用“注入”来遍历您的密钥,并跟踪看到的最新默认设置...像这样:
def value(Map presets, String... keys) {
keys.inject([pos: presets, result: presets.default]) { latest, current ->
def node = latest.pos[current]
if (node instanceof Map) {
[pos: node, result: node.default ?: latest.result]
} else if (node instanceof String) {
[pos: node, result: node]
} else if (node == null) {
[pos: node, result: latest.result]
} else {
throw new RuntimeException("No idea what to do with a ${node.class.simpleName}")
}
}.result
}
然后就可以了(用上面的例子)
// Defaults
assert value(presets, 'TeamUnknown', "AppName2", "Component14") == 'preset_default'
assert value(presets, 'Team1', "AppName2", "Component14") == 'preset_team1Default'
// Values
assert value(presets, 'Team1', "AppName2", "Component1") == 'preset_team1App2Comp1'
一个简单的通用递归会有所帮助:
def input = new groovy.json.JsonSlurper().parseText '''{
"presets": {
"default": "preset_default",
"Team1":{
"AppName1":{
"Component1": "preset_team1App1Comp1",
"default" : "preset_team1App1Default"
},
"AppName2":{
"Component1": "preset_team1App2Comp1",
"Component2": "preset_team1App2Comp2"
},
"default" : "preset_team1Default"
},
"Team2":{
"AppName1":{
"Component1": "preset_team2App1Comp1"
}
}
}
}'''
def findRecursive
findRecursive = { json, List keys, List defaults = [] ->
if( !json || ( json in String ) || !keys ) return json
if( json.default ) defaults << json.default
findRecursive json[ keys.remove( 0 ) ] ?: defaults.last(), keys, defaults
}
assert 'preset_team1App1Comp1' == findRecursive( input.presets, [ 'Team1', 'AppName1', 'Component1' ] )
assert 'preset_team2App1Comp1' == findRecursive( input.presets, [ 'Team2', 'AppName1', 'Component1' ] )
assert 'preset_team1Default' == findRecursive( input.presets, [ 'Team1', 'AppName3', 'Component1' ] )
assert 'preset_default' == findRecursive( input.presets, [ 'Team3' ] )
assert 'preset_default' == findRecursive( input.presets, [ 'Team2', 'AppName2', 'Component1' ] )
另一种方式
def value(presets, team, app, compt) {
def defkey = 'default'
return presets.get(team)?.get(app)?.get(compt) ?:
presets.get(team)?.get(app)?.get(defkey) ?:
presets.get(team)?.get(defkey) ?:
presets.get(defkey)
}
assert value(presets, 'TeamUnknown', "AppName2", "Component14") == 'preset_default'
assert value(presets, 'Team1', "AppName2", "Component14") == 'preset_team1Default'
assert value(presets, 'Team1', "AppName2", "Component1") == 'preset_team1App2Comp1'