Groovy 中的内联条件映射文字

vic*_*csz 5 groovy

使用 Groovy 中的 Maps/JsonBuilder 处理一些翻译/映射功能。

是否可以(无需在地图文字创建之外创建额外的代码).. 有条件地包含/排除某些键/值对?一些类似于以下内容的事情..

 def someConditional = true   

 def mapResult = 
        [
           "id":123,
           "somethingElse":[],
           if(someConditional){ return ["onlyIfConditionalTrue":true]}
        ]
Run Code Online (Sandbox Code Playgroud)

预期结果:如果someConditional为false,则mapResult中将只存在2个键/值对。

如果 someConditional 为 true,则所有 3 个键/值对都将存在。

请注意,我确信如果我创建方法 / 并将其拆分,就可以完成。为了保持简洁,我希望将内容保留在地图创建中。

cfr*_*ick 5

您可以帮助自己with

[a:1, b:2].with{
    if (false) {
        c = 1
    }
    it
}
Run Code Online (Sandbox Code Playgroud)

有了小帮手:

Map newMap(m=[:], Closure c) {
    m.with c
    m
}
Run Code Online (Sandbox Code Playgroud)

例如:

def m = newMap {
    a = 1
    b = 1
    if (true) {
        c = 1
    }
    if (false) {
        d = 1
    }
}

assert m.a == 1
assert m.b == 1
assert m.c == 1
assert !m.containsKey('d')
Run Code Online (Sandbox Code Playgroud)

或者传递一个初始地图:

newMap(a:1, b:2) {
    if (true) {
        c = 1
    }
    if (false) {
        d = 1
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑

从 Groovy 2.5 开始,有一个with名为的替代方案tap。它的工作原理类似于with但不返回闭包的返回值,而是返回委托。所以这可以写成:

[a:1, b:2].tap{
    if (false) {
        c = 1
    }
}
Run Code Online (Sandbox Code Playgroud)