我经常编写
形式的代码(->> init
(map ...)
(filter ...)
(first))
当将其转换为使用传感器的代码时,我最终会得到像
这样的东西(transduce (comp (map ...) (filter ...)) (completing #(reduced %2)) nil init)
写(completing #(reduced %2))
代替first
根本不适合我。它毫无疑问地模糊了一项非常直接的任务。是否有更惯用的方式来执行此任务?
答案 0 :(得分:2)
我个人会使用自定义缩减功能的方法,但这里有一些选择:
(let [[x] (into [] (comp (map inc) (filter even?) (take 1)) [0 1])]
x)
使用破坏:/
或者:
(first (eduction (map inc) (filter even?) [0 1])
在这里,您可以节省为您完成的comp
呼叫。虽然它不是超级懒惰。它将实现多达32个元素,因此可能会浪费。
修正了(take 1)
:
(first (eduction (map inc) (filter even?) (take 1) [0 1]))
总体来说,与以下相比更短,并且不太清楚:
(transduce (comp (map inc) (filter even?) (take 1)) (completing #(reduced %2)) nil [0 1])
如果你需要这一堆,那么我可能 NOT 创建一个自定义的reducer函数,而是一个类似于transform的函数,它将xform, coll
作为参数并返回第一个值。它更清楚它的作用,你可以给它一个很好的文档字符串。如果您想在保留致电comp
时保存,也可以使其与eduction
:
(defn single-xf
"Returns the first item of transducing the xforms over collection"
{:arglists '([xform* coll])}
[& xforms]
(transduce (apply comp (butlast xforms)) (completing #(reduced %2)) nil (last xforms)))
示例:
(single-xf (map inc) (filter even?) [0 1])
答案 1 :(得分:0)