假设我有以下列表:
val myList = List(Map(1 -> 1), Map(2 -> 2), Map(2 -> 7))
我想将此列表转换为Int的单个地图 - >清单(INT)。如果我们有重复的键,则两个值都应包含在结果值列表中。
Map(2 -> List(7,2),1 -> List(1))
我提出了这个有效的解决方案,但看起来过于笨重。
myList.foldLeft(scala.collection.mutable.Map[Int,List[Int]]()) {(result,element) =>
for((k,v) <- element) {
if (result.keySet.contains(k)) {
result(k) = result(k).:: (v)
} else {
result += (k -> List(v))
}
}
result
}
这里有更好或更有效的方法吗?
答案 0 :(得分:5)
myList
.flatten
.groupBy(_._1)
.mapValues(_.map(_._2))
答案 1 :(得分:1)
您可以使用更简单(但效率可能更低)的代码:
Fragment
地图(2 - &gt;列表(2,7),1 - &gt;列表(1))
我们的想法是先从所有内部val myList = List(Map(1 -> 1), Map(2 -> 2), Map(2 -> 7))
val grouped = myList.flatMap(_.toList).groupBy(_._1).mapValues(l => l.map(_._2))
println(grouped)
获取所有元组的List
,然后将它们分组。
答案 2 :(得分:0)
从Scala 2.13
开始,我们现在可以使用groupMap
,它等效于groupBy
后跟mapValues
(如其名称所示)的单次通过:
// val maps = List(Map(1 -> 1), Map(2 -> 2), Map(2 -> 7))
maps.flatten.groupMap(_._1)(_._2) // Map(1 -> List(1), 2 -> List(2, 7))
此:
flatten
将地图列表转换为元组列表(List((1, 1), (2, 2), (2, 7))
)
group
的元素基于它们的第一个元组部分(_._1
)(组地图的组部分)
map
的值分为第二个元组部分(_._2
)(组 Map 的映射部分)