Dictionary 如何在groovy中执行条件收集

Dictionary 如何在groovy中执行条件收集,dictionary,collections,groovy,Dictionary,Collections,Groovy,是否可以进行条件收集,如收集 [ a:1, b:2, c:3, d:4 ].findAll { it.value > 2 } 应该这样做这应该可以: [a:1, b:2, c:3, d:4].collectEntries { if (it.value > 2) ["${it.key}": it.value] } 它没有你想象的那么简洁;但就记录而言,您可以使用collectEntries执行以下操作: [ a:1, b:2, c:3, d:4 ].coll

是否可以进行条件收集,如收集

[ a:1, b:2, c:3, d:4 ].findAll { it.value > 2 }
应该这样做

这应该可以:

[a:1, b:2, c:3, d:4].collectEntries {
    if (it.value > 2)
        ["${it.key}": it.value]
}
它没有你想象的那么简洁;但就记录而言,您可以使用
collectEntries
执行以下操作:

[ a:1, b:2, c:3, d:4 ].collectEntries { 
    it.value > 2 ? [(it.key) : it.value] : [:] }
评估结果是

[c:3, d:4]
如果出现错误,则该键将最终成为GStringImpl类的实例,而不是字符串。答案本身在REPL中看起来不错,但如果您检查它是什么类,您会发现它是错误的:

groovy:000> m = [ a:1, b:2, c:3, d:4 ]
===> [a:1, b:2, c:3, d:4]
groovy:000> m.collectEntries { ["${it.key}" : it.value ] }
===> [a:1, b:2, c:3, d:4]
groovy:000> _.keySet().each { println(it.class) }
class org.codehaus.groovy.runtime.GStringImpl
class org.codehaus.groovy.runtime.GStringImpl
class org.codehaus.groovy.runtime.GStringImpl
class org.codehaus.groovy.runtime.GStringImpl
===> [a, b, c, d]

试图将GroovyString等同于普通字符串的代码,即使字符串看起来完全相同,也会计算为false,从而导致一个难以识别的错误。

添加else后,它现在可以工作了。谢谢

[a:1, b:2, c:3, d:4].collectEntries {
    if (it.value > 2){
        ["${it.key}": it.value]
    }else{
      [:]
    }
}

按原样抛出NPE。您需要一个
else[:]
这并不能解决Nathan Hughes指出的问题,密钥将是
GStringImpl
的实例,而不是常规字符串。要将变量用作映射键,只需将它们用大括号括起来:
[(it.key):it.value]