【问题标题】:How to count the occurrence of an element in a nested Map in Scala?如何计算 Scala 中嵌套 Map 中元素的出现次数?
【发布时间】:2020-02-08 07:03:34
【问题描述】:

我想找到一种有效的方法来计算位于两级映射中的列表中元素的出现次数。

内部映射可能具有非唯一键,例如deep1 存在于shallow1shallow2 中。向量之间可能存在非唯一值。例如1 出现在shallow1 -> deep1shallow2 -> 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)))

我希望得到

地图(1 -> 2, 2 -> 1, 3 -> 2, 7 -> 2, 8 -> 2, 9 -> 1)

【问题讨论】:

  • @LuisMiguelMejíaSuárez 编辑了这个问题,谢谢。

标签: scala functional-programming hashmap


【解决方案1】:

2.13 的另一种解决方案,它尽可能通用(和高效)
(您可以通过更改 updatedWith 轻松地将其调整为适用于 2.12IterableOnce)

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)
    }
  }
}

【讨论】:

  • @smaug 类似于acc.get(key = t) match { case Some(count) =&gt; acc + (t -&gt; (count + 1)) case None =&gt; acc + (t -&gt; 1) }
【解决方案2】:

你可以用这个

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

产生预期的输出:

地图(1 -> 2, 9 -> 1, 2 -> 1, 7 -> 2, 3 -> 2, 8 -> 2)

【讨论】:

    【解决方案3】:

    这是一种方法,将嵌套的 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+。

    【讨论】:

      猜你喜欢
      • 2012-08-03
      • 2018-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-13
      • 1970-01-01
      • 2022-11-30
      • 2012-07-12
      相关资源
      最近更新 更多