Clojure 中是否有一个相当于“first”的归约函数?
Is there a reducing function in Clojure that performs the equivalent of `first`?
我经常写这种形式的代码
(->> init
(map ...)
(filter ...)
(first))
将其转换为使用转换器的代码时,我会得到类似
的结果
(transduce (comp (map ...) (filter ...)) (completing #(reduced %2)) nil init)
写 (completing #(reduced %2))
而不是 first
根本不适合我。它不必要地掩盖了一个非常简单的任务。是否有更惯用的方式来执行此任务?
medley has find-first
with a transducer arity and xforms 有一个称为 last
的归约函数。我认为两者的结合就是您所追求的。
(ns foo.bar
(:require
[medley.core :as medley]
[net.cgrand.xforms.rfs :as rfs]))
(transduce (comp (map ,,,) (medley/find-first ,,,)) rfs/last init)
我个人会使用你的方法和自定义减少函数,但这里有一些替代方法:
(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 函数,而是创建一个类似于 transduce 的函数,它以 xform, coll
作为参数returns 第一个值。它的作用更清楚,你可以给它一个很好的文档字符串。如果你想节省调用 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])
我经常写这种形式的代码
(->> init
(map ...)
(filter ...)
(first))
将其转换为使用转换器的代码时,我会得到类似
的结果(transduce (comp (map ...) (filter ...)) (completing #(reduced %2)) nil init)
写 (completing #(reduced %2))
而不是 first
根本不适合我。它不必要地掩盖了一个非常简单的任务。是否有更惯用的方式来执行此任务?
medley has find-first
with a transducer arity and xforms 有一个称为 last
的归约函数。我认为两者的结合就是您所追求的。
(ns foo.bar
(:require
[medley.core :as medley]
[net.cgrand.xforms.rfs :as rfs]))
(transduce (comp (map ,,,) (medley/find-first ,,,)) rfs/last init)
我个人会使用你的方法和自定义减少函数,但这里有一些替代方法:
(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 函数,而是创建一个类似于 transduce 的函数,它以 xform, coll
作为参数returns 第一个值。它的作用更清楚,你可以给它一个很好的文档字符串。如果你想节省调用 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])