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
when we
groupBy
(docs), we obtain another map whose keys are the values found inintMap
, and whose values is a "submap" ofintMap
, that only contains the relevant entriesnow 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 originalintMap
Let's say you want to know how many 5
s 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.