reduce & folds in Clojure
Bakery loaf orders folded with reduce, including a fold into a map.
;; reduce folds a two-argument function across a collection
(def loaves [4 9 2 7])
(println (reduce + loaves))
;; an init value seeds the accumulator and covers the empty case
(println (reduce + 100 loaves) (reduce + 0 []))
(def orders [{:item "rye" :loaves 4} {:item "sour" :loaves 9}
{:item "rye" :loaves 2}])
;; reducing into a map: fnil supplies the 0 the first time a key lands
(def per-item
(reduce (fn [acc {:keys [item loaves]}]
(update acc item (fnil + 0) loaves))
{} orders))
;; min and max fall out of reduce given the right two-argument fn
(println per-item (reduce min loaves) (reduce max loaves))
How it works
(reduce + loaves)folds with no init value, and(reduce + 0 [])shows what an init covers.per-itemreduces the order maps into a totals map, where(fnil + 0)supplies the zero on a key's first appearance.(reduce min loaves)and(reduce max loaves)pull the extremes from the same fold.
Keywords and builtins used here
deffnfnilmaxminprintlnreduceupdate
The run, in numbers
- Lines
- 18
- Characters to type
- 614
- Tokens
- 110
- Three-star pace
- 70 tpm
At the three-star pace of 70 tokens a minute, this run takes about 94 seconds.
Step 2 of 3 in Sequences, step 14 of 27 in Language basics.