在Groovy中调用链(compose)方法

时间:2015-06-19 06:27:51

标签: groovy clojure

我有一个变量和几个我想在一个序列中调用的方法,其中一个方法的返回值是另一个方法的输入。基本上是一条管道。现在,有没有一种链接电话的方式?在伪代码中它看起来像

def a = [1, 2, 3]
def b = calculation3(calculation2(calculation1(a)))

你可以看到它看起来很像Clojure,我想最终得到类似的东西(使用Clojure语法)

(-> a 
   calculation1
   calculation2
   calculation3)

我希望使用with关键字但它只传递变量a而不收集结果并将它们作为输入传递给下一个方法。

到目前为止,我发现的唯一可行解决方案就是这样的'封闭组合'。但这似乎对我来说太沉重了。

def a = [1, 2, 3]
def b = (class1.&calculation1 >> class1.&calculation2 >> class1.&calculation3)(a)

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

您可以编写一个函数来执行此操作:

def chain(a, Closure... fns) {
    fns.toList().inject(a) { v, c -> c(v) }
}

然后在您的代码中调用它:

chain(a, class1.&calculation1,class1.&calculation2,class1.&calculation3)

答案 1 :(得分:2)

我多想了一下,想出了类似的东西:

def compose = {...c ->
   {result ->
      c.each {
         result = it(result)
      }
   result
   }
}

def a = [1, 2, 3]
def b = compose(class1.&calculation1, class1.&calculation2, class1.&calculation3)(a)

它还不如Clojure的线程好。

答案 2 :(得分:0)

使用inject

def pipe(fn, ...fns) {
    { args ->
        fns.inject(fn(args)) { acc, value ->
            value(acc)
        }
    }
}

不允许第一个函数采用可变数量的参数,而不允许以下参数。