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 を使用した Tim Yates の回答ほど簡潔ではありません。ただし、記録のために、これを行うために使用できます。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 に答える