如何以“Groovy”的方式编写相互关联的方法/闭包?

时间:2016-02-19 15:38:31

标签: groovy closures

我需要将配置值的Map转换为如下字符串:

{“key”=> “value”,“key2”=> “value2”,...}

有时候一个值可能是配置值的另一个映射,所以对于那个值,我需要像递归调用一样回到同一个转换过程中,产生:

{...“key3”=> {“subkey”=> “subvalue”,...},...}

我来自Java背景,并且正在努力寻找基于Groovy / closure的正确方法来实现这一目标。这是我到目前为止所做的:

static String toConfigString(Map config) {
    return "{${config.collect {toConfigEntryString(it)}.join(', ')}}"
}

static String toConfigEntryString(entry) {
    return "\"$entry.key\" => ${entry.value instanceof Map ? toConfigString(entry.value) : "\"$entry.value\""}"
}

由于第一个方法调用第二个方法,第二个方法转回并调用回第一个方法,我不知道如何写这个,比如说,一个像样的闭包我可以传递到初始收集调用......

2 个答案:

答案 0 :(得分:0)

使用递归:

def map = [
    a: 1,
    b: 2,
    c: [
        d: 4, 
        e: [ f: 5, g: 7 ]
    ]
]

def convertToString(Map item) {
    item.collect { k, v ->
        v instanceof Map ? "{'$k' => ${convertToString(v).join(/, /)} }" : "{'$k' => '$v'}"
    } 
}

assert convertToString( map ).join(/, /) == 
 /{'a' => '1'}, {'b' => '2'}, {'c' => {'d' => '4'}, {'e' => {'f' => '5'}, {'g' => '7'} } }/

答案 1 :(得分:0)

Groovy可以根据运行时的类型选择调用哪个方法。你可以定义两个函数:一个用于Map,一个用于所有其他情况,只需递归调用函数

def dump(object) {
  "'${object}'"
}
def dump(Map config) {
​​​​​​​​​​​​  '{' + ​config.collect { key, value -> "'${key}' => ${dump(value)}" }.join(", ")​​​​​​​​​​​​​​​​​​​​​ + '}'
}

def s = [a:"prop", b:[key:"value"]]
assert dump(s) == "{'a' => 'prop', 'b' => {'key' => 'value'}}"