Back
reduce (clj)
(source)function
(reduce f coll)
(reduce f val coll)
f should be a function of 2 arguments. If val is not supplied,
returns the result of applying f to the first 2 items in coll, then
applying f to that result and the 3rd item, etc. If coll contains no
items, f must accept no arguments as well, and reduce returns the
result of calling f with no arguments. If coll has only 1 item, it
is returned and f is not called. If val is supplied, returns the
result of applying f to val and the first item in coll, then
applying f to that result and the 2nd item, etc. If coll contains no
items, returns val and f is not called.
Examples
clojure
(ns clojure.test-clojure.reducers
(:require [clojure.core.reducers :as r]
[clojure.test.generative :refer (defspec)]
[clojure.data.generators :as gen])
(:use clojure.test))
(defmacro defequivtest
;; f is the core fn, r is the reducers equivalent, rt is the reducible ->
;; coll transformer
[name [f r rt] fns]
`(deftest ~name
(let [c# (range -100 1000)]
(doseq [fn# ~fns]
(is (= (~f fn# c#)
(~rt (~r fn# c#))))))))
(deftest test-mapcat-obeys-reduced
(is (= [1 "0" 2 "1" 3]
(->> (concat (range 100) (lazy-seq (throw (Exception. "Too eager"))))
(r/mapcat (juxt inc str))
(r/take 5)
(into [])))))
(defequivtest test-reduce
[reduce r/reduce identity]
[+' *'])
(deftest test-sorted-maps
(let [m (into (sorted-map)
'{1 a, 2 b, 3 c, 4 d})]
(is (= "1a2b3c4d" (reduce-kv str "" m))
"Sorted maps should reduce-kv in sorted order")
(is (= 1 (reduce-kv (fn [acc k v]
(reduced (+ acc k)))
0 m))
"Sorted maps should stop reduction when asked")))
(deftest test-nil
(is (= {:k :v} (reduce-kv assoc {:k :v} nil)))
(is (= 0 (r/fold + nil))))
(defn reduced-at-probe
[m p]
(reduce-kv (fn [_ k v] (when (== p k) (reduced :foo))) nil m))
(defspec reduced-always-returns
(fn [probe to-end]
(let [len (+ probe to-end 1)
nums (range len)
m (zipmap nums nums)]
(reduced-at-probe m probe)))
[^{:tag `gen-num} probe ^{:tag `gen-num} to-end]
(assert (= :foo %)))
(deftest test-closed-over-clearing
;; this will throw OutOfMemory without proper reference clearing
(is (number? (reduce + 0 (r/map identity (range 1e8))))))
penpot/penpot
#_:clj-kondo/ignore
(ns app.common.data.macros
"Data retrieval & manipulation specific macros."
(:refer-clojure :exclude [get-in select-keys str with-open min max])
#?(:cljs (:require-macros [app.common.data.macros]))
(:require
#?(:clj [clojure.core :as c]
:cljs [cljs.core :as c])
[app.common.data :as d]
[cljs.analyzer.api :as aapi]
[cuerdas.core :as str]))
(defmacro with-open
[bindings & body]
{:pre [(vector? bindings)
(even? (count bindings))
(pos? (count bindings))]}
(reduce (fn [acc bindings]
`(let ~(vec bindings)
(try
~acc
(finally
(d/close! ~(first bindings))))))
`(do ~@body)
(reverse (partition 2 bindings))))
TechEmpower/FrameworkBenchmarks
(ns io.github.kit-clj.te-bench.cache.inmem
(:require
[clojure.core.cache :as cache]
[integrant.core :as ig]
[next.jdbc :as jdbc]
[next.jdbc.result-set :as rs]))
(defmethod ig/init-key :cache/inmem
[_ {:keys [db-conn threshold]}]
(cache/fifo-cache-factory
(reduce
(fn [out {:keys [id] :as obj}]
(assoc out id obj))
{}
(jdbc/execute! db-conn ["select * from \"World\""] {:builder-fn rs/as-unqualified-lower-maps}))
{:threshold threshold}))
babashka/babashka
(ns babashka.impl.protocols
(:require [babashka.impl.protocols :as protocols]
[clojure.core.protocols :as p]
[clojure.datafy :as d]
;; ensure datafy is loaded, we're going to override its
;; clojure.lang.Namespace implementation for datafy
[clojure.reflect]
[sci.core :as sci :refer [copy-var]]
[sci.impl.types :as types]
[sci.impl.vars]))
;; IKVReduce only added for satisies? check for now. We can implement
;; kv-reduce in the future, but this needs patching some functions like
;; update-vals, etc.
'IKVReduce (sci/new-var 'clojure.core.protocols/IKVReduce {:protocol p/IKVReduce
;; :methods #{'kv-reduce}
:ns protocols-ns}
{:ns protocols-ns})
;; 'kv-reduce (copy-var kv-reduce protocols-ns)
}
)
thheller/shadow-cljs
(ns shadow.remote.runtime.cljs.js-builtins
(:require
[goog.object :as gobj]
[clojure.core.protocols :as p]))
(extend-protocol p/Datafiable
;; FIXME: this is kind of a bad idea
;; can't do this for all objects, since none of the CLJS types implement this
;; protocol either. the protocol dispatch will end up using object
;; FIXME: this could detect CLJS types to some extent
;; or should it just implement the protocols for the types?
object
(datafy [o]
(if-not (identical? (.-__proto__ o) js/Object.prototype)
o
(with-meta
(->> (gobj/getKeys o)
(reduce
(fn [m key]
(assoc! m key (gobj/get o key)))
(transient {}))
(persistent!))
jonase/eastwood
(ns testcases.unusednss3
(:require [clojure.core.protocols :as protocols]
[clojure.core.reducers :as reducers]
[clojure.data :as data]
[clojure.java.io :as io]
[clojure.reflect :as reflect]))
(extend String
protocols/IKVReduce
{:kv-reduce (fn [amap f init] nil)})
(extend-protocol reducers/CollFold
String
(coll-fold [coll n combinef reducef] nil))