我知道该->表单可用于将一个函数结果的结果传递给另一个:
(f1 (f2 (f3 x)))
(-> x f3 f2 f1) ; equivalent to the line above
Run Code Online (Sandbox Code Playgroud)
但是,此表单要求您知道要在设计时使用的功能.我想做同样的事情,但在运行时使用任意函数列表.
我已经编写了这个循环函数,但是我觉得有更好的方法:
(defn pipe [initialData, functions]
(loop [
frontFunc (first functions)
restFuncs (rest functions)
data initialData ]
(if frontFunc
(recur (first restFuncs) (rest restFuncs) (frontFunc data) )
data )
) )
Run Code Online (Sandbox Code Playgroud)
最好的方法是什么?
jan*_*dot 20
我必须承认我对clojure很新,我可能完全忽略了这一点,但这不能用comp和apply来完成吗?
user> (defn fn1 [x] (+ 2 x))
user> (defn fn2 [x] (/ x 3))
user> (defn fn3 [x] (* 1.2 x))
user> (defn pipe [initial-data my-functions] ((apply comp my-functions) initial-data))
user> (pipe 2 [fn1 fn2 fn3])
2.8
Run Code Online (Sandbox Code Playgroud)
你可以用一个普通的老人做到这一点reduce:
(defn pipe [x fs] (reduce (fn [acc f] (f acc)) x fs))
Run Code Online (Sandbox Code Playgroud)
这可以缩短为:
(defn pipe [x fs] (reduce #(%2 %1) x fs))
Run Code Online (Sandbox Code Playgroud)
像这样使用:
user> (pipe [1 2 3] [#(conj % 77) rest reverse (partial map inc) vec])
[78 4 3]
Run Code Online (Sandbox Code Playgroud)