Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala Iterables映射-在给定键下向iterable添加值的通用方法_Scala - Fatal编程技术网

Scala Iterables映射-在给定键下向iterable添加值的通用方法

Scala Iterables映射-在给定键下向iterable添加值的通用方法,scala,Scala,我可以为向量编写以下内容: 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,Vecto

我可以为向量编写以下内容:

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))
集合的代码几乎相同:

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))
}
如何使单个函数适用于所有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))
}
但在本例中,我丢失了类型信息:

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)))
}
def add[K,V,I[u3;](map.get(key).map(3;++值).getOrElse(值)))
}
但它没有编译:

无法基于Repr类型的集合构造包含Any类型元素的类型集合。 [错误]map+(键->(map.get(键).map(++值).getOrElse(值)))


丑陋的实例但有效:)

def add[K,V,I[V](map.get(key).map(++values.asInstanceOf[Iterable[V]]).getOrElse(values)))
m、 asInstanceOf[Map[K,I[V]]
}
scala控制台的结果:

scala> def add[K,V,I[V] <: Iterable[V]](map: Map[K,I[V]], key: K, values: I[V]): Map[K,I[V]] = {
     |        val m: Map[K, Iterable[Any]] =  map + (key -> (map.get(key).map(_ ++ values.asInstanceOf[Iterable[V]]).getOrElse(values)))
     |        m.asInstanceOf[Map[K, I[V]]]
     | }
warning: there were 1 feature warning(s); re-run with -feature for details
add: [K, V, I[V] <: Iterable[V]](map: Map[K,I[V]], key: K, values: I[V])Map[K,I[V]]

scala> add(Map(1 -> Vector(1,2,3)), 1, Vector(4,5,6))
res0: Map[Int,scala.collection.immutable.Vector[Int]] = Map(1 -> Vector(1, 2, 3, 4, 5, 6))

scala> add(Map(1 -> Set(1,2,3)), 1, Set(4,5,6))
res1: Map[Int,scala.collection.immutable.Set[Int]] = Map(1 -> Set(5, 1, 6, 2, 3, 4))
scala>def add[K,V,I[V](map.get(key).map(++values.asInstanceOf[Iterable[V]]).getOrElse(values)))
|m.asInstanceOf[Map[K,I[V]]
| }
警告:有1个功能警告;有关详细信息,请使用-feature重新运行
添加:[K,V,I[V]添加(映射(1->向量(1,2,3)),1,向量(4,5,6))
res0:Map[Int,scala.collection.immutable.Vector[Int]]=Map(1->Vector(1,2,3,4,5,6))
scala>add(映射(1->Set(1,2,3)),1,Set(4,5,6))
res1:Map[Int,scala.collection.immutable.Set[Int]]=Map(1->Set(5,1,6,2,3,4))

您需要使用
CanBuildFrom
通过
++
调用传递有关已使用集合的类型信息。有关此信息,请参阅
TraversableLike
上的
++
重载

以下工作(不关心细节,如未定义的键)

def添加[K,V,It(映射(K)++vs))

有没有一种方法可以在没有完全指定类型签名的情况下使用该函数?我无法想象一直在编写这些类型。@tokarev我看了第二眼,删除了一个不必要的类型参数。它现在应该可以工作了。Scala正在运行中。我想在t恤衫上打印此代码Instanceof是一种代码味道。+1用于工作解决方案生长激素
scala> def add[K,V,I[V] <: Iterable[V]](map: Map[K,I[V]], key: K, values: I[V]): Map[K,I[V]] = {
     |        val m: Map[K, Iterable[Any]] =  map + (key -> (map.get(key).map(_ ++ values.asInstanceOf[Iterable[V]]).getOrElse(values)))
     |        m.asInstanceOf[Map[K, I[V]]]
     | }
warning: there were 1 feature warning(s); re-run with -feature for details
add: [K, V, I[V] <: Iterable[V]](map: Map[K,I[V]], key: K, values: I[V])Map[K,I[V]]

scala> add(Map(1 -> Vector(1,2,3)), 1, Vector(4,5,6))
res0: Map[Int,scala.collection.immutable.Vector[Int]] = Map(1 -> Vector(1, 2, 3, 4, 5, 6))

scala> add(Map(1 -> Set(1,2,3)), 1, Set(4,5,6))
res1: Map[Int,scala.collection.immutable.Set[Int]] = Map(1 -> Set(5, 1, 6, 2, 3, 4))
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))