Scala 将地图的地图数组转换为带有地图列表的地图



我有一个地图数组,想合并类似的键并将它们的值组合成一个列表。有没有一种优雅的方法可以做到这一点,最好不引入任何新库或更新 scala?斯卡拉版本 2.11.12

(Map("a" -> Map(1 -> 1.1)),
Map("a" -> Map(2 -> 2.1)),
Map("b" -> Map(1 -> 1.1)),
Map("c" -> Map(1 -> 1.1)),
Map("c" -> Map(2 -> 2.2)))

输出:

Map(
"a" -> List(Map(1 -> 1.1), Map(2 -> 2.1)),
"b" -> List(Map(1 -> 1.1)),
"c" -> List(Map(1 -> 1.1), Map(2 -> 2.2)))

编辑以解释为什么它不是重复的:Scala:合并地图 该答案不会动态地浏览整个列表并合并相同的键,它只会合并给出的 2 个特定映射。正如答案所举例说明的那样,真正的解决方案与迭代列表的优雅方式有关,不仅合并列表,而且首先将地图加载到列表中,然后合并它们。

你可以试试下面


val map = List(
Map("a" -> Map(1 -> 1.1)),
Map("a" -> Map(2 -> 2.1)),
Map("b" -> Map(1 -> 1.1)),
Map("c" -> Map(1 -> 1.1)),
Map("c" -> Map(2 -> 2.2))
)
val merged = map.fold(Map.empty[String, List[Map[Int, Double]]]) { (a, b) =>
a ++ b.map { case (k, v) => (k, (v :: a.get(k).toList.flatten).reverse) }
}
merged.foreach(println)
/****** output ******
(a,List(Map(1 -> 1.1), Map(2 -> 2.1)))
(b,List(Map(1 -> 1.1)))
(c,List(Map(1 -> 1.1), Map(2 -> 2.2)))
*********************/

我会编写自己的函数来做到这一点。作为初学者,以下是以下几行:

type acc = Map[String, List[Map[Int, Int]]]
@tailrec
def merge(map: Map[String, Map[Int, Int]], acc): acc = map match {
case Nil => acc
case x :: xs =>
val (key, value) = x
if (acc.contains(key)) // append the value to the existing List and then call the merge method again
else // create the new key and call the merge method again 
}

确保每次调用合并方法时都使用新的 acc(累加器(!

最新更新