100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

map, filter, reduce in Clojure

Master the three foundational sequence-processing functions that let you transform, select, and accumulate data declaratively instead of writing explicit loops.

Functional ProgrammingBeginner9 min readJul 10, 2026
Analogies

The Core Sequence Trio: map, filter, reduce

map, filter, and reduce are the three foundational sequence-processing functions in Clojure, and together they let you express most data transformations without writing explicit loops. map applies a function to every element and returns a new lazy sequence of results; filter keeps only elements satisfying a predicate; reduce collapses a sequence into a single accumulated value by repeatedly applying a two-argument function.

🏏

Cricket analogy: A scorer who goes through every ball, converting raw deliveries into run values with map, then only keeps boundary balls with filter, then sums them for a boundary count with reduce, demonstrates the trio in a single innings analysis.

map: Transforming Every Element

map takes a function and one or more collections and returns a lazy sequence of applying that function positionally across them; passing multiple collections lets you zip and transform in one step, and map stops as soon as the shortest input is exhausted. Because the result is lazy, (map f coll) does no work until something forces (realizes) the sequence, such as printing it or wrapping it in doall.

🏏

Cricket analogy: Pairing each ball of an over with the bowler's intended line, a multi-collection map of deliveries and lines, produces a combined analysis row per ball, just like (map + coll1 coll2).

clojure
(map inc [1 2 3]) ;=> (2 3 4)
(map + [1 2 3] [10 20 30]) ;=> (11 22 33)
(map str ["a" "b"] ["x" "y"]) ;=> ("ax" "by")

filter: Selecting Elements

filter takes a predicate and a collection and returns a lazy sequence containing only the elements for which the predicate returns truthy; remove is filter's mirror image, keeping elements the predicate rejects. Because Clojure treats nil and false as the only falsy values, predicates can return any truthy value (not just true/false) and filter will still work correctly.

🏏

Cricket analogy: A selector keeping only bowlers with an economy rate under 6 from the full squad list is filter applied to player stats.

clojure
(filter even? [1 2 3 4 5 6]) ;=> (2 4 6)
(filter #(> % 10) [5 15 8 20]) ;=> (15 20)
(remove even? [1 2 3 4 5 6]) ;=> (1 3 5)

filter and map are lazy — wrapping side-effecting functions (like println) inside them can appear to do nothing until the sequence is realized by something like doall, into, or printing it. Chunked sequences can also realize more elements than expected, causing side effects to fire in unexpected batches.

reduce: Accumulating a Result

reduce walks a collection left to right, repeatedly calling a two-argument function with an accumulator and the next element, and returns the final accumulated value; supplying an explicit initial value avoids surprises when the collection is empty or has one element. Because map and filter are really special cases of the fold pattern reduce embodies, understanding reduce deeply — including reduced for early termination — unlocks writing your own sequence-processing HOFs.

🏏

Cricket analogy: Running total of a team's score, ball by ball, where each delivery's runs get added to a rolling accumulator, is exactly reduce with + as the combining function.

clojure
(reduce + 0 [1 2 3 4]) ;=> 10

(reduce (fn [acc x] (if (> x 100) (reduced acc) (+ acc x)))
        0 [10 20 30 200 40]) ;=> 60

(reduce conj [] [1 2 3]) ;=> [1 2 3]

reduce is eager, unlike map and filter — calling reduce forces the entire (possibly lazy) input sequence to be realized in order to compute the final result.

  • map applies a function across one or more collections positionally and returns a lazy sequence of results.
  • filter keeps only elements for which a predicate returns truthy; remove keeps the opposite.
  • reduce folds a collection into a single accumulated value using a two-argument combining function.
  • map and filter are lazy — nothing is computed until the sequence is realized.
  • Providing an explicit initial value to reduce avoids edge-case bugs with empty or single-element collections.
  • reduced allows early termination from inside a reduce without processing the rest of the collection.
  • map, filter, and reduce compose naturally into multi-stage data-processing pipelines.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#ClojureStudyNotes#MapFilterReduceInClojure#Map#Filter#Reduce#Clojure#StudyNotes#SkillVeris#ExamPrep