【问题标题】:How to call a closure with multiple parameters from collect() method of a groovy collection?如何从 groovy 集合的 collect() 方法调用具有多个参数的闭包?
【发布时间】:2011-12-03 23:58:20
【问题描述】:

假设我有一个闭包:

def increment = {value, step ->
   value + step 
}

现在我想遍历整数集合的每个项目,将其递增 5,并将新元素保存到新集合中:

def numbers = [1..10]
def biggerNumbers = numbers.collect {
      it + 5
} 

现在我想通过使用increment 闭包来获得相同的结果。我怎样才能做到这一点?

应该是这样的(下面的错误代码):

def biggerNumbers = numbers.collect increment(it, 5) //what's the correct name of 'it'??

【问题讨论】:

    标签: collections groovy closures


    【解决方案1】:

    解决您的问题的方法是将您的增量调用嵌套在一个闭包中:

    def biggerNumbers = numbers.collect {increment(it, 5)}
    

    如果您想将预制闭包传递给 collect,您应该使其与 collect 兼容 - 接受一个参数:

    def incrementByFive = {it + 5}
    def biggerNumbers = numbers.collect incrementByFive
    

    【讨论】:

      【解决方案2】:

      mojojojo 有正确的答案,但我想补充一下,这看起来像是 currying(特别是 using rcurry)的一个很好的候选者

      如果你有:

      def increment = {value, step ->
         value + step 
      }
      

      然后您可以使用以下命令对该函数的右侧参数进行柯里化:

      def incrementByFive = increment.rcurry 5
      

      然后,你可以这样做:

      def numbers = 1..10
      def biggerNumbers = numbers.collect incrementByFive
      

      只是觉得它可能很有趣;-)

      【讨论】:

      • 有趣的建议,但你在numbers.collect { incrementByFive it } 中犯了一个小错误,当numbers.collect incrementByFive 足够时实例化一个冗余闭包。类似的事情会导致开销,尽管 Groovy 与性能无关。
      • @mojojojo 很好,谢谢 :-) 修复了代码,因为在未来为人们提供次优示例是没有意义的 :-)
      【解决方案3】:

      主要问题是[1..10] 创建了一个List<IntRange>,您正在尝试增加它。您应该直接在 IntRange 上collect(注意缺少括号):

      (1..10).collect { it + 5 }
      

      或者加咖喱:

      def sum = { a, b -> a + b }
      (1..10).collect(sum.curry(5))
      

      【讨论】:

        猜你喜欢
        • 2011-10-14
        • 2013-11-06
        • 1970-01-01
        • 2019-03-16
        • 2021-10-23
        • 1970-01-01
        • 2013-07-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多