【发布时间】:2012-11-22 18:34:55
【问题描述】:
是否可以像 collect 那样做一个有条件的 collectEntries ?
【问题讨论】:
标签: dictionary collections groovy
是否可以像 collect 那样做一个有条件的 collectEntries ?
【问题讨论】:
标签: dictionary collections groovy
[ a:1, b:2, c:3, d:4 ].findAll { it.value > 2 }
应该这样做
【讨论】:
没有Tim Yates's answer using findAll那么简洁;但为了记录,您可以使用collectEntries 来执行此操作:
[ a:1, b:2, c:3, d:4 ].collectEntries {
it.value > 2 ? [(it.key) : it.value] : [:] }
计算结果为
[c:3, d:4]
Using "${it.key}" as done in this answer 是一个错误,键最终将是 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,从而导致难以解决的错误。
【讨论】:
这应该可行:
[a:1, b:2, c:3, d:4].collectEntries {
if (it.value > 2)
["${it.key}": it.value]
}
【讨论】:
else [:]
添加 else 后它现在可以工作了。谢谢
[a:1, b:2, c:3, d:4].collectEntries {
if (it.value > 2){
["${it.key}": it.value]
}else{
[:]
}
}
【讨论】:
GStringImpl 的实例,而不是常规字符串。要将变量用作映射键,只需用大括号将它们括起来:[(it.key): it.value]