我想在所有集合中添加方法product()
并使用它,就像我可以使用sum()
一样。
我可以通过x.inject { a, b -> a * b }
获取列表的产品,但我希望能够x.product()
。
到目前为止,我已经尝试了
Collection.metaClass.product = {-> delegate.inject { a, b -> a * b } }
x = [1,2,3,4]
println(x.product())
但这会导致
Caught: groovy.lang.MissingMethodException: No signature of method: java.util.ArrayList.inject() is applicable for argument types: (Util$_run_closure1_closure2) values: [Util$_run_closure1_closure2@161bb7fe]
Possible solutions: inject(java.lang.Object, groovy.lang.Closure), inject(java.lang.Object, groovy.lang.Closure), inspect(), toSet(), collect(), collect()
groovy.lang.MissingMethodException: No signature of method: java.util.ArrayList.inject() is applicable for argument types: (Util$_run_closure1_closure2) values: [Util$_run_closure1_closure2@161bb7fe]
Possible solutions: inject(java.lang.Object, groovy.lang.Closure), inject(java.lang.Object, groovy.lang.Closure), inspect(), toSet(), collect(), collect()
at Util$_run_closure1.doCall(Util.groovy:1)
at Util.run(Util.groovy:4)
答案 0 :(得分:1)
这是一个可以通过在Groovy控制台中运行代码来测试的解决方案
// implement method
Collection.metaClass.product = {
if (!delegate) {
return null
}
delegate.inject {a, b -> a * b}
}
// test it
assert [1,2,3].product() == 6
assert [].product() == null
稍长但更易读(IMO)的解决方案是:
Collection.metaClass.product = {
if (!delegate) {
return null
}
def result = 1
delegate.each {
result *= it
}
result
}
答案 1 :(得分:1)
想出来。
出于任何完全奇怪的原因,groovysh允许x.inject { a, b -> a * b }
,但是当我在groovysh之外编译它时,这个爆炸了。更改为x.inject(1) { a, b -> a * b }
后,一切都按预期工作。