map, filter, and reduce
Prerequisites: Functions, Lists and vectors
Three functions replace most loops.
(def prices [12 5 30 8 20])
(println (map #(* 2 %) prices)) ; transform each item
(println (filter #(> % 10) prices)) ; keep matching items
(println (remove #(> % 10) prices)) ; drop matching items
(println (reduce + prices)) ; combine into one value
(println (reduce + 100 prices)) ; with a starting value
(24 10 60 16 40)
(12 30 20)
(5 8)
75
175
(map f coll)callsfon every item and returns a sequence of the results.(filter pred coll)keeps items for whichpredreturns truthy;removekeeps the others.(reduce f init coll)combines items two at a time:(f (f (f init a) b) c).
map with several collections
(println (map + [1 2 3] [10 20 30]))
(println (map vector [:a :b :c] [1 2 3]))
(println (map str "abc" (range))) ; stops at the shortest
(println (map-indexed (fn [i x] (str i ":" x)) [:a :b]))
(11 22 33)
([:a 1] [:b 2] [:c 3])
(a0 b1 c2)
(0::a 1::b)
reduce builds anything
(def words ["apple" "banana" "avocado" "cherry" "blueberry"])
(println (reduce (fn [longest w] (if (> (count w) (count longest)) w longest)) words))
(println (reduce (fn [acc w] (update acc (first w) (fnil conj []) w))
{}
words))
blueberry
{a [apple avocado], b [banana blueberry], c [cherry]}
The accumulator can be any value — a number, a string, a map. The second example builds a map from first letter to words.
Other everyday helpers
(def nums [3 8 12 5 20 7])
(println (some even? nums)) ; any match? (returns the pred's value)
(println (every? pos? nums)) ; all match?
(println (first (filter #(> % 10) nums)))
(println (count (filter odd? nums)))
(println (mapv inc nums)) ; mapv/filterv return vectors
(println (keep #(when (odd? %) (* % %)) nums))
true
true
12
3
[4 9 13 6 21 8]
(9 25 49)
keep is map that drops nil results — a filter and a map in one.
Practice
From [3 8 12 5 20 7], print the sum of the squares of the even
numbers.
Show solution
(def nums [3 8 12 5 20 7])
(println (reduce + (map #(* % %) (filter even? nums))))
608