Skip to content
AgileLogics
6 min read

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) calls f on every item and returns a sequence of the results.
  • (filter pred coll) keeps items for which pred returns truthy; remove keeps 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