Created By: Geoffrey Challen
/ Updated: 2022-05-23

In this lesson we'll introduce a new programming paradigm that is particular useful for working with data: map-reduce-filter. We'll manipulated linear collections of data using good old for loops. But we can do better. Let's see how!

Iterative Building Blocks

Many of the code and algorithms we've written together have operated on sequential data, stored in either arrays or Lists. And we've seen and identified common patterns for working with this kind of data. Such as counting:

And searching:

And transforming:

And filtering:

And combining:

And while these are fine building blocks for creating larger programs, there is something a bit repetitive and dull about them. Every one has the same overall structure: the same loop, many have an if statement, etc. Shouldn't there be a better, more compact way of expressing these kind of patterns?


Yes. There is. In Kotlin we refer to this as map-reduce-filter, which is also sometimes known as stream data processing.

map-reduce-filter allows us to work with sequential data by composing powerful programming primitives to great effect. These methods are built right in to all of the Kotlin collections—arrays, lists, and maps—that we've already been working with!

Let's examine how to utilize common stream operations to replace the repetitive loop-based code we wrote above. First, let's look at one of the most basic collection operations—map:

Show how to use map to transform a list.

We can also filter streams using... filter. Let's see how:

Describe filter.

And, we can even reduce a Stream until a single value with reduce, a surprisingly powerful primitive.

Show how to use reduce.

Why map-reduce-filter?

This programming pattern may seem alien to you at first. That's not surprising. A famous silicon valley tech thought leader has pointed out that powerful programming ideas usually feel strange and even bizarre at first. But, as you come to appreciate them, not only do they become more natural, but the older less-powerful ways of doing things start to see even more limited.

Compared to for loops, map-reduce-filter pipelines are:

  • More succint: the common parts of the various for-loop based patterns we've listed above have been factored out, leaving only the decision-making logic that changes depending on the application
  • More composable: it is easier to reorder stream operations to accomplish different data processing tasks than it is to tease apart different parts of for loop
  • More efficient: collection operators allow various kinds of operations (like map, for example) to be done in parallel, increasing the speed with which large collections can be processed

map-reduce-filter Example

To wrap up, let's have some fun working with one of our favorite data sets:

Do a few map-reduce-filter operations using collections of Dogs. Identify a few other operations like sum and sorted.

Show how to complete the homework problem above. Feel free to cover multiple approaches!

More Practice

Need more practice? Head over to the practice page.