Как посчитать вхождение элемента во вложенную карту в Scala? - PullRequest
1 голос
/ 10 октября 2019

Я хочу найти эффективный способ подсчета вхождений элемента в список, расположенный на двухуровневой карте.

Внутренние карты могут содержать неуникальные ключи, например, deep1 существует в shallow1 и shallow2. Могут быть неуникальные значения по векторам. Например, 1 встречается в shallow1 -> deep1 и shallow2 -> deep1, но у каждого вектора нет повторяющихся значений.

Например, для следующей карты

val twoLevelMap: Map[String, Map[String, Vector[Int]]] = Map(
  "shallow1" -> Map(
    "deep1" -> Vector(1, 3, 7),
    "deep2" -> Vector(3, 8)),
  "shallow2" -> Map(
    "deep1" -> Vector(1, 2),
    "deep4" -> Vector(7, 8, 9)))

Я ожидаю, чтоget

Карта (1 -> 2, 2 -> 1, 3 -> 2, 7 -> 2, 8 -> 2, 9 -> 1)

Ответы [ 3 ]

3 голосов
/ 10 октября 2019

Другое решение для 2.13, которое является как можно более общим (и эффективным) .
(Вы можете легко адаптировать его для работы на 2.12, изменив updatedWith иIterableOnce) .

def countInnerValues[T, C[x] <: IterableOnce[x]](nestedMap: Map[String, Map[String, C[T]]]): Map[T, Int] = {
  val iterator = for {
    innerMaps <- nestedMap.valuesIterator
    innerValues <- innerMaps.valuesIterator
    value <- innerValues.iterator
  } yield value


  iterator.foldLeft(Map.empty[T, Int]) { (acc, t) =>
    acc.updatedWith(key = t) {
      case Some(count) => Some(count + 1)
      case None        => Some(1)
    }
  }
}
2 голосов
/ 10 октября 2019

Вот один из подходов - сглаживание вложенных значений Map, после чего следует groupMapReduce:

twoLevelMap.flatMap(_._2.values).flatten.
  groupMapReduce(identity)(_ => 1)(_ + _)
// res1: scala.collection.immutable.Map[Int,Int] =
//   HashMap(1 -> 2, 9 -> 1, 2 -> 1, 7 -> 2, 3 -> 2, 8 -> 2)

Обратите внимание, что для groupMapReduce требуется Scala 2.13 +.

2 голосов
/ 10 октября 2019

Вы можете использовать это

twoLevelMap.flatMap(_._2.values).flatten.groupBy(identity).mapValues(_.size)

, которое дает ожидаемый результат:

Карта (1 -> 2, 9 -> 1, 2 -> 1, 7 -> 2, 3 -> 2, 8 -> 2)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...