typestar

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

  1. (reduce + loaves) folds with no init value, and (reduce + 0 []) shows what an init covers.
  2. per-item reduces the order maps into a totals map, where (fnil + 0) supplies the zero on a key's first appearance.
  3. (reduce min loaves) and (reduce max loaves) pull the extremes from the same fold.

Keywords and builtins used here

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.

Type this snippet

Step 2 of 3 in Sequences, step 14 of 27 in Language basics.

← Previous Next →