Вот эффективное однопроходное решение:
ranges
.map(r => r -> nums.count(n => n >= r._1 && n <= r._2))
.toMap
Это позволяет избежать затрат на создание списка чисел, а затем сжать их с диапазонами на отдельном шаге.
Это версия, в которой используется больше функций Scala, но она слишком причудлива:
(for {
r <- ranges
range = r._1 to r._2
} yield r -> nums.count(range.contains)
).toMap
Это также менее эффективно, потому что contains
должен учитывать диапазоны со значением шага и поэтому является более сложным.
А вот еще более эффективная версия, позволяющая избежать любых временных структур данных:
val result: Map[(Int, Int), Int] =
ranges.map(r => r -> nums.count(n => n >= r._1 && n <= r._2))(collection.breakOut)
См. Это объяснение breakOut
, если вы не знакомы с ним. Использование breakOut
означает, что вызов map
создаст Map
напрямую, а не List
, который должен быть преобразован в Map
с использованием toMap
.