3

ベクトルについては、次のように記述できます。

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))
}

使用法:

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))

Sets のコードはほとんど同じです。

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))
}

すべてのイテラブルで機能する単一の関数を作成するには? 私は次のように書いてみました:

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))
}

しかし、この場合、型情報を失いました:

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))

私は次のことを試しました:

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)))
}

しかし、それはコンパイルされませんでした:

タイプ Repr のコレクションに基づいて、タイプ Any の要素を持つタイプ That のコレクションを構築できません。[エラー] map + (key -> (map.get(key).map(_ ++ values).getOrElse(values)))

4

2 に答える 2

5

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))
于 2013-08-23T12:56:59.340 に答える