add avg and juxt
This commit is contained in:
parent
5d20db6ba3
commit
e576631ca4
2 changed files with 34 additions and 3 deletions
|
|
@ -41,7 +41,11 @@ Add this dependency to your project:
|
||||||
Execution time mean : 20,604297 µs
|
Execution time mean : 20,604297 µs
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`avg` is a reducing fn to compute the arithmetic mean. `juxt` is used to compute several reducing fns at once.
|
||||||
|
```clj
|
||||||
|
=> (into {} (x/by-key odd? (x/reduce (x/juxt + x/avg))) (range 256))
|
||||||
|
{0 [16256 127], 1 [16384 128]}
|
||||||
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
(ns net.cgrand.xforms
|
(ns net.cgrand.xforms
|
||||||
"Extra transducers for Clojure"
|
"Extra transducers for Clojure"
|
||||||
{:author "Christophe Grand"}
|
{:author "Christophe Grand"}
|
||||||
(:refer-clojure :exclude [reduce for partition str])
|
(:refer-clojure :exclude [reduce for partition str juxt])
|
||||||
(:require [clojure.core :as clj]))
|
(:require [clojure.core :as clj]))
|
||||||
|
|
||||||
(defmacro for
|
(defmacro for
|
||||||
|
|
@ -27,7 +27,8 @@
|
||||||
([~acc ~binding] ~body)))))
|
([~acc ~binding] ~body)))))
|
||||||
|
|
||||||
(defn reduce
|
(defn reduce
|
||||||
"A transducer that reduces a collection to a 1-item collection consisting of only the reduced result."
|
"A transducer that reduces a collection to a 1-item collection consisting of only the reduced result.
|
||||||
|
Unlike reduce but like transduce it does call the completing arity (1) of the reducing fn."
|
||||||
([f]
|
([f]
|
||||||
(fn [rf]
|
(fn [rf]
|
||||||
(let [vacc (volatile! (f))]
|
(let [vacc (volatile! (f))]
|
||||||
|
|
@ -88,5 +89,31 @@
|
||||||
(vswap! m assoc! k noprf))
|
(vswap! m assoc! k noprf))
|
||||||
(unreduced acc))))))))
|
(unreduced acc))))))))
|
||||||
|
|
||||||
|
(defn avg
|
||||||
|
"Reducing fn to compute the arithmetic mean."
|
||||||
|
([]
|
||||||
|
(let [count (volatile! 0)
|
||||||
|
sum (volatile! 0)]
|
||||||
|
(fn secret-container
|
||||||
|
([] (when (pos? @count) (/ @sum @count)))
|
||||||
|
([n]
|
||||||
|
(vswap! count inc)
|
||||||
|
(vswap! sum + n)
|
||||||
|
secret-container))))
|
||||||
|
([acc] (acc))
|
||||||
|
([acc x] (acc x)))
|
||||||
|
|
||||||
|
(defn juxt
|
||||||
|
"Returns a reducing fn which compute all rfns at once and whose final return
|
||||||
|
value is a vector of the final return values of each rfns."
|
||||||
|
[& rfns]
|
||||||
|
(let [rfns (vec rfns)]
|
||||||
|
(fn
|
||||||
|
([] (mapv #(vector % (volatile! (%))) rfns))
|
||||||
|
([acc] (mapv (fn [[rf vacc]] (rf (unreduced @vacc))) acc))
|
||||||
|
([acc x]
|
||||||
|
(let [some-unreduced (reduce (fn [some-unreduced [rf vacc]]
|
||||||
|
(when-not (reduced? @vacc) (vswap! vacc rf x) true))
|
||||||
|
false acc)]
|
||||||
|
(if some-unreduced acc (reduced acc)))))))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue