首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将一组映射合并到一个映射中?

如何将一组映射合并到一个映射中?
EN

Stack Overflow用户
提问于 2022-11-03 01:03:50
回答 2查看 38关注 0票数 0

当前

代码语言:javascript
复制
+-------+---------------------------------------------------------------------------+
|ID     |map                                                                        |
+-------+---------------------------------------------------------------------------+
|105    |[{bia, {4 -> 1}}, {compton, {5 -> 1}}, {alcatraz, {3 -> 6}}]               |
|106    |[{compton, {4 -> 5}}]                                                      |
|107    |[{compton, {5 -> 99}}]                                                     |
|108    |[{bia, {1 -> 5}}, {compton, {1 -> 1}}]                                     |
|101    |[{alcatraz, {1 -> 2}}]                                                     |
|102    |[{alcatraz, {1 -> 2}}]                                                     |
|103    |[{alcatraz, {1 -> 2}}, {alcatraz, {2 -> 2}}, {alcatraz, {3 -> 2}}]         |
|104    |[{alcatraz, {1 -> 4}}, {alcatraz, {2 -> 2}}, {alcatraz, {3 -> 2}}]         |
+-------+---------------------------------------------------------------------------+

所需

代码语言:javascript
复制
+-------+---------------------------------------------------------------------------+
|ID     |map                                                                        |
+-------+---------------------------------------------------------------------------+
|105    |{bia, {4 -> 1}}, {compton, {5 -> 1}}, {alcatraz, {3 -> 6}}                 |
|106    |{compton, {4 -> 5}}                                                        |
|107    |{compton, {5 -> 99}}                                                       |
|108    |{bia, {1 -> 5}}, {compton, {1 -> 1}}                                       |
|101    |{alcatraz, {1 -> 2}}                                                       |
|102    |{alcatraz, {1 -> 2}}                                                       |
|103    |{alcatraz, {1 -> 2, 2 -> 2, 3 -> 2}                                        |
|104    |{alcatraz, {1 -> 4, 2 -> 2, 3 -> 2}                                         |
+-------+---------------------------------------------------------------------------+

我希望最终的映射是,第一个映射级别是位置的关键(例如,alcatrazbiacompton),第二级是代表组的数字,最终值是计数。

我通过做这样的事情得到了当前的桌子:

代码语言:javascript
复制
.groupBy(col("ID")).agg(collect_list(map($"LOCATION", map($"GROUP", $"COUNT"))) as "map")

为了更清晰起见,JSON表示所需的格式

代码语言:javascript
复制
{
    "alcatraz": {
        "1": 100,
        "2": 300
    }, 
    "bia": {
        "2": 767
    },
    "compton": {
        "1": 888,
        "2": 999,
        "3": 1000
    }, 

}

我看到了其他一些用于合并简单映射的堆栈溢出帖子,但是因为它是地图的映射,所以这些解决方案都不起作用。

我一直在和udf一起玩,但运气不好。在scala中有一个简单的方法来实现我的目标吗?

EN

回答 2

Stack Overflow用户

发布于 2022-11-03 01:38:12

我最后所做的是使用这个定义的udf:

代码语言:javascript
复制
    val joinMap = udf { values: Seq[Map[String, Map[String, Int]]] => {
      var newMap: scala.collection.mutable.Map[String, Map[String, Int]] = scala.collection.mutable.Map[String, Map[String, Int]]()
      for (value <- values) {
        for ((k, v) <- value) {
          for ((sub_k, sub_v) <- v) {
            if (newMap.contains(k)) {
              newMap(k) += (sub_k -> sub_v)
            } else {
              newMap(k) = v
            }
          }
        }
      }
      newMap
    } }

你可以通过做

代码语言:javascript
复制
.withColumn("map", joinMap(col("map")))
票数 0
EN

Stack Overflow用户

发布于 2022-11-03 17:57:25

如果您的作用域中有,您可以这样做:

代码语言:javascript
复制
def mergeMaps(values: Seq[Map[String, Map[String, Int]]]): Map[String, Map[String, Int]] = {
  import cats.implicits._
  values.foldLeft(Map.empty)(_ |+| _)
}

(注意:猫提供了更紧凑的语法,但这将使其更不明显。)

但是要小心:如果两个“内部映射”有相同的键,上面会添加整数值,因此Seq(Map("1" -> Map("1" -> 1)), Map("1" -> Map("1" -> 1)))将合并到Map("1" -> Map("1" -> 2))中。如果这是一个问题,并且需要与解决方案中的行为完全相同的行为,您可以这样修改解决方案:

代码语言:javascript
复制
def mergeMaps(values: Seq[Map[String, Map[String, Int]]]): Map[String, Map[String, Int]] = {
  import cats.implicits._
  implicit val takeRightIntSemiGroup = new cats.Semigroup[Int] {
    def combine(x: Int, y: Int): Int = y
  }
  values.foldLeft(Map.empty)(_ |+| _)
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74297149

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档