12

是否可以像 collect 这样有条件的 collectEntries ?

4

4 回答 4

13
[ a:1, b:2, c:3, d:4 ].findAll { it.value > 2 }

应该这样做

于 2012-11-22T18:45:24.120 回答
7

它不像蒂姆耶茨使用 findAll 的回答那样简洁;但只是为了记录,您可以使用它collectEntries来执行此操作:

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

评估为

[c:3, d:4]

在这个答案中使用“${it.key}”是一个错误,密钥最终将成为 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]

即使字符串看起来相同,试图将 GroovyStrings 等同于普通字符串的代码也会评估为 false,从而导致难以弄清楚的错误。

于 2015-07-27T14:20:37.130 回答
-1

这应该有效:

[a:1, b:2, c:3, d:4].collectEntries {
    if (it.value > 2)
        ["${it.key}": it.value]
}
于 2012-11-22T18:50:50.387 回答
-1

添加其他内容后,它现在可以工作了。谢谢

[a:1, b:2, c:3, d:4].collectEntries {
    if (it.value > 2){
        ["${it.key}": it.value]
    }else{
      [:]
    }
}
于 2020-08-07T13:11:07.833 回答