'How to convert list of integers to a map with frequency per bin?

Lets say I have a list of numbers:

val numbers = List(15, 30, 110, 140, 170, 210)

How can I count the number of integers per bin of a 100 in order to get:

Map(0 -> 2, 100 -> 3, 200 -> 1)


Solution 1:[1]

// val items = List(1, 2, 3, 101, 330, 302)
items.groupBy(i => i/100).map { case (i, l) => (i*100, l.length) }
// Map(100 -> 1, 300 -> 2, 0 -> 3)

Solution 2:[2]

Starting Scala 2.13, you can use the groupMapReduce method which is (as its name suggests) an equivalent of a groupBy followed by a map and a reduce step on values:

// val items = List(1, 2, 3, 101, 330, 302)
items.groupMapReduce(_ / 100 * 100)(_ => 1)(_ + _)
// Map(0 -> 3, 100 -> 1, 300 -> 2)

This:

  • groups items by their associated "bin" (_ / 100 * 100 e.g. 330 / 100 * 100 = 300) (group part of groupMapReduce)

  • maps grouped values to 1 (_ => 1) (map part of groupMapReduce)

  • reduces values within each group (_ + _) by summing them (reduce part of groupMapReduce).

This is a one-pass version of what can be translated by:

items.groupBy(_ / 100 * 100).mapValues(_.map(_ => 1).reduce(_ + _)).toMap

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Xavier Guihot
Solution 2 Xavier Guihot