Last Updated: February 25, 2016
·
4.625K
· pagoda_5b

How to count instances of values in a Map

This is a pretty common use case that I often stumble into, especially as scala newcomers' questions.

That's why I want to share this really basic tip.

Assume we have a Map of Int -> Int values, generated randomly

val intMap = (for (id <- 1 to 100) yield (id, Random.nextInt(10))).toMap

> intMap: scala.collection.immutable.Map[Int,Int] = Map(69 -> 2, 88 -> 8, 5 -> 3, 10 -> 9, ... )

Scala collections allows you to group the entries specifying the grouping criteria with a lambda expression.

So we can group our map by distinct values, and then count the instances for each value by mapping on the resulting submaps getting their size.

In code this means

val occurrences = intMap groupBy {case (id, value) => value} mapValues (_.size)

> occurrences: scala.collection.immutable.Map[Int,Int] = Map(0 -> 10, 5 -> 8, 1 -> 11, 6 -> 10, 9 -> 9, 2 -> 13, 7 -> 9, 3 -> 10, 8 -> 14, 4 -> 6)

Or using a shorter syntax

val occurrences = intMap groupBy (_._2) mapValues (_.size)

Let's explore this step by step

  1. when we groupBy(docs), we obtain another map whose keys are the values found in intMap, and whose values is a "submap" of intMap, that only contains the relevant entries

  2. now we only need to transform each submap with mapValues(docs) by getting his corresponding size, to know how many occurrences there were for each value in the original intMap


Let's say you want to know how many 5s there were in the map

val howmanyfives = occurrences(5)

> howmanyfives: Int = 8

Or, better still, in a typesafe fashion

val howmanypossiblyfive = occurrences get 5
> howmanypossiblyfive: Option[Int] = Some(8)

Enjoy your histagram.