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

map, filter, and reduce

Master Scala's core higher-order functions for transforming, selecting, and aggregating collections declaratively instead of writing manual loops.

CollectionsIntermediate9 min readJul 10, 2026
Analogies

Higher-Order Functions on Collections

map, filter, and reduce (along with its cousin fold) are higher-order functions available uniformly across every Scala collection type - List, Vector, Set, Map, and more - because they're defined once on shared traits like Iterable and Seq rather than reimplemented per collection. Each takes a function literal as an argument, letting you express a data transformation declaratively: describe what should happen to each element or how results should combine, rather than manually writing an imperative loop with mutable counters and index variables.

🏏

Cricket analogy: map, filter, and reduce being available on every Scala collection is like every format of cricket - Tests, ODIs, T20s - sharing the same core rules of batting and bowling, letting a captain apply the same tactical playbook (a function literal) regardless of which format's scorecard (List, Vector, Set) they're managing.

Transforming Elements with map

map applies a given function to every element of a collection and returns a new collection of the same size, though the element type can change entirely - for example, List[Int].map(_.toString) produces a List[String]. flatMap is closely related: it's used when the mapping function itself returns a collection per element (such as splitting a sentence into words), and it automatically flattens one level of nesting so you end up with a single flat collection rather than a collection of collections.

🏏

Cricket analogy: runsScored.map(_ * 2) doubling every player's runs for a fundraiser exhibition match is like a scoreboard operator applying the same multiplier to every name on the card - the number of players stays the same, only the values change - while flatMap on a List of overs, each yielding a List of balls, flattens the nested structure into one continuous ball-by-ball sequence.

scala
val prices: List[Double] = List(19.99, 5.50, 42.00)
val withTax: List[Double] = prices.map(_ * 1.08)

val words: List[String] = List("scala", "is", "fun")
val lengths: List[Int] = words.map(_.length)

// flatMap flattens a List[List[A]] produced by mapping into a single List[A]
val sentences: List[String] = List("hello world", "scala rocks")
val allWords: List[String] = sentences.flatMap(_.split(" ").toList)
// List("hello", "world", "scala", "rocks")

Selecting Elements with filter

filter keeps only the elements that satisfy a Boolean predicate, and filterNot keeps only the elements that don't - both return a collection of the same type but with (possibly) fewer elements. collect goes a step further by accepting a partial function: the case guard performs the filtering while the case body performs the mapping, so filtering and transforming happen together in a single traversal instead of two separate passes over the data.

🏏

Cricket analogy: scores.filter(_ >= 50) pulling out every half-century from an innings is like a highlights producer selecting only the big-hitting knocks, while scores.collect { case s if s >= 100 => s * bonusRate } combines the filtering and the bonus-calculation into a single pass, like a sponsor computing century bonuses in one sweep of the scorecard.

collect combines filtering and mapping in a single pass using a partial function: nums.collect { case n if n % 2 == 0 => n * n } keeps only even numbers and squares them at once, avoiding a separate .filter(...).map(...) traversal.

Aggregating with reduce, fold, and foldLeft

reduce combines every element of a collection pairwise using an associative binary operator, but it has no initial value to fall back on, so calling it on an empty collection throws an UnsupportedOperationException. foldLeft (and foldRight) instead take an explicit initial "zero" value as a separate argument list, so they can safely process an empty collection by simply returning that zero value, and they can also accumulate into a different type than the collection's element type - foldLeft processes strictly left-to-right, threading the running accumulator through each step in order.

🏏

Cricket analogy: partnershipRuns.reduce(_ + _) totaling a batting partnership's runs works fine mid-innings, but throws if the partnership List is empty - like asking for a partnership total before any ball's been bowled - while partnershipRuns.foldLeft(0)(_ + _) safely starts from zero runs even in a fresh, unstarted innings.

scala
val orderTotals: List[Double] = List(25.0, 40.0, 15.5)

val total: Double = orderTotals.reduce(_ + _)             // 80.5, throws if list is empty
val totalSafe: Double = orderTotals.foldLeft(0.0)(_ + _)  // 80.5, safe on empty list too

val summary: String =
  orderTotals.foldLeft("Orders: ")((acc, amt) => acc + f"$$$amt%.2f ")

reduce and reduceLeft throw an UnsupportedOperationException when called on an empty collection because there's no initial value to fall back on. Whenever the collection might legitimately be empty, use fold/foldLeft with an explicit zero value instead.

  • map, filter, and reduce/fold are higher-order functions defined uniformly across Scala's collection types.
  • map transforms every element with a function, preserving the collection's size while potentially changing its element type.
  • flatMap is like map followed by flattening, useful when the mapping function itself returns a collection.
  • filter keeps only elements satisfying a predicate; filterNot keeps only elements that don't.
  • collect combines filtering and mapping in one pass using a partial function.
  • reduce combines elements pairwise but throws on an empty collection; fold/foldLeft take an explicit zero value and work safely on empty collections.
  • foldLeft processes elements left-to-right, threading an accumulator through each step.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#ScalaStudyNotes#MapFilterAndReduce#Map#Filter#Reduce#Higher#StudyNotes#SkillVeris#ExamPrep