我有一些嵌套的地图,如:
val map1 = Map("key1"->1, "key2"->Map("x"->List(1,2)))
val map2 = Map("key3"->3, "key2"->Map("y"->List(3,4)))
我想合并它们以获得结果图,如;
val res = Map("key1"->1, "key2"->Map("x"->List(1,2), "y"->List(3,4)), "key3"->3)
因此嵌套地图也应该合并。 地图和嵌套地图的类型可以假设为Map [String,Any]。如果两个映射具有冲突键(例如,相同键的值不同,除了该值是嵌套映射),则认为是异常。
这有一些优雅的解决方案吗? 谢谢!
答案 0 :(得分:2)
以下内容如何:
type MapType = Map[String, Any]
def merge(map1 : MapType, map2 : MapType) = (map1.keySet ++ map2.keySet)
.map(key => key -> mergeValues(map1.get(key), map2.get(key)))
.toMap
private def mergeValues(o1 : Option[Any], o2 : Option[Any]) = (o1, o2) match {
case (Some(v1 : MapType), Some(v2 : MapType)) => v1 ++ v2
case _ => (o1 orElse o2).get
}
您可以修改mergeValues
函数以支持其他情况(即当相同的键指向2个非映射值的情况时 - 此时将返回第一个值)。
答案 1 :(得分:2)
type MapType = Map[String, Any]
def merge(map1 : MapType, map2 : MapType) = (map1.keySet ++ map2.keySet)
.map(key => key -> mergeValues(map1.get(key), map2.get(key)))
.toMap
private def mergeValues(o1 : Option[Any], o2 : Option[Any]) = (o1, o2) match {
case (Some(v1), Some(v2)) => merge(v1.asInstanceOf[MapType], v2.asInstanceOf[MapType])
case _ => (o1 orElse o2).get
}
norbert-radyk的改进版本:
non-variable type argument String in type pattern scala.collection.immutable.Map[String,Any] (the underlying of MapType) is unchecked since it is eliminated by erasure
case (Some(v1 : MapType), Some(v2 : MapType)) => v1 ++ v2