Monthly Archives: November 2019

Scala’s groupMap And groupMapReduce

For grouping elements in a Scala collection by a provided key, the de facto method of choice has been groupBy, which has the following signature for an Iterable:

It returns an immutable Map of elements each consisting of a key and a collection of values of the original type. To process this collection of values in the resulting Map, Scala provides a method mapValues with the below signature:

This groupBy/mapValues combo proves to be handy for processing the values of the Map generated from the grouping. However, as of Scala 2.13, method mapValues is no longer available.

groupMap

A new method, groupMap, has emerged for grouping of a collection based on provided functions for defining the keys and values of the resulting Map. Here’s the signature of method groupMap for an Iterable:

Let’s start with a simple example grouping via the good old groupBy method:

We can replace groupBy with groupMap like below:

In this particular case, the new method doesn’t offer any benefit over the old one.

Let’s look at another example that involves a collection of class objects:

If we want to list all pet names per species, a groupBy coupled with mapValues will do:

But in this case, groupMap can do it with better readability due to the functions for defining the keys and values of the resulting Map being nicely placed side by side as parameters:

groupMapReduce

At times, we need to perform reduction on the Map values after grouping of a collection. This is when the other new method groupMapReduce comes in handy:

Besides the parameters for defining the keys and values of the resulting Map like groupMap, groupMapReduce also expects an additional parameter in the form of a binary operation for reduction.

Using the same pets example, if we want to compute the count of pets per species, a groupBy/mapValues approach will look like below:

With groupMapReduce, we can “compartmentalize” the functions for the keys, values and reduction operation separately as follows:

One more example:

Let’s say we want to compute the monthly total of list price and discounted price of the product list. In the groupBy/mapValues way:

Using groupMapReduce: