Is there a shrinking function in Clojure that does the equivalent of `first`?

I often write form code

(->> init
     (map ...)
     (filter ...)
     (first))

By converting this to code that uses converters, I get something like

(transduce (comp (map ...) (filter ...)) (completing #(reduced %2)) nil init)

Writing (completing #(reduced %2))instead firstdoesn't suit me at all. This shamelessly hides a very simple task. Is there a more idiomatic way to accomplish this?

+4
source share
2 answers

I personally would use your approach with a custom reduction function, but here are a few alternatives:

(let [[x] (into [] (comp (map inc) (filter even?) (take 1)) [0 1])]
    x)

Use of destruction: /

Or:

(first (eduction (map inc) (filter even?) [0 1])

This is where you save the call compthat is being made for you. Although this is not super lazy. It implements up to 32 elements, so it can be wasteful. Fixed with (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])

, , , , , transduce, 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])
+2

medley find-first 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)
0

Source: https://habr.com/ru/post/1690246/


All Articles