我可以为Vectors编写以下内容:
def add[K,V](map: Map[K,Vector[V]], key: K, values: Vector[V]): Map[K,Vector[V]] = {
map + (key -> (map.getOrElse(key, Vector.empty) ++ values))
}
Run Code Online (Sandbox Code Playgroud)
用法:
scala> add(Map(1 -> Vector(1,2,3)), 1, Vector(4,5,6))
res1: Map[Int,Vector[Int]] = Map(1 -> Vector(1, 2, 3, 4, 5, 6))
Run Code Online (Sandbox Code Playgroud)
集的代码几乎相同:
def add[K,V](map: Map[K,Set[V]], key: K, values: Set[V]): Map[K,Set[V]] = {
map + (key -> (map.getOrElse(key, Set.empty) ++ values))
}
Run Code Online (Sandbox Code Playgroud)
如何制作适用于所有Iterables的单一功能?我试着像这样写:
def add[K,V](map: Map[K,Iterable[V]], key: K, values: Iterable[V]): Map[K,Iterable[V]] = {
map + (key -> (map.getOrElse(key, Iterable.empty) ++ values))
}
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,我丢失了类型信息:
scala> add(Map(1 -> Set(1,2,3)), 1, Set(4,5,6))
res4: Map[Int,Iterable[Int]] = Map(1 -> Set(5, 1, 6, 2, 3, 4))
Run Code Online (Sandbox Code Playgroud)
我尝试了以下方法:
def add[K,V,I[_] <: Iterable[_]](map: Map[K,I[V]], key: K, values: I[V]): Map[K,I[V]] = {
map + (key -> (map.get(key).map(_ ++ values).getOrElse(values)))
}
Run Code Online (Sandbox Code Playgroud)
但它没有编译:
无法根据Repr类型的集合构造类型为Any的元素类型的集合.[error] map +(key - >(map.get(key).map(_ ++ values).getOrElse(values)))
您需要使用CanBuildFrom通过++调用来引导有关已使用集合的类型信息.请参阅++on 的重载TraversableLike.
以下工作(不关心细节,如未定义的键).
def add[K,V,It <: TraversableLike[V,It]]
(map: Map[K,It],k: K, vs: Traversable[V])
(implicit bf: CanBuildFrom[It,V,It])
:Map[K,It] =
map + (k -> (map(k) ++ vs))
Run Code Online (Sandbox Code Playgroud)