Scala 展平集合地图

Scala 展平集合地图,scala,Scala,我试图将关键点可遍历的地图展平,即: Map( Set(1, 2, 3) -> 'A', Set(4, 5, 6) -> 'B') 应展平至: Map(5 -> B, 1 -> A, 6 -> B, 2 -> A, 3 -> A, 4 -> B) 以下是我所做的: def fuse[A, B, T <: Traversable[A]](mapOfTravs: Map[T, B]): Map[A, B] = { val pairs =

我试图将关键点可遍历的地图展平,即:

Map( Set(1, 2, 3) -> 'A', Set(4, 5, 6) -> 'B')
应展平至:

Map(5 -> B, 1 -> A, 6 -> B, 2 -> A, 3 -> A, 4 -> B)
以下是我所做的:

def fuse[A, B, T <: Traversable[A]](mapOfTravs: Map[T, B]): Map[A, B] = {
  val pairs = for {
    trav <- mapOfTravs.keys
    key <- trav
  } yield (key, mapOfTravs(trav))
  pairs.toMap
}   

注意:当键可遍历项具有非空交集时,此
fuse
函数没有多大意义。

这基本上是您在中所做的,以便于理解,但简化了一点:

  def fuse[A, B, T <: Traversable[A]](mapOfTravs: Map[T, B]): Map[A, B] = {
    mapOfTravs.flatMap({ case (s, c) => s.map(i => i -> c) })
  }
def fuse[A,B,T s.map(i=>i->c)}
}
关于类型你做不了多少,我肯定你可以做一些lambda类型的恶作剧,我只是不知道怎么做

更新 这里有一个稍好的for版本,与上面的平面图相同:

  def fuse2[A, B, T <: Traversable[A]](mapOfTravs: Map[T, B]): Map[A, B] = {
    for {
      (keys, value) <- mapOfTravs
      key <- keys
    } yield key -> value
  }

def fuse2[A,B,T这看起来很可怕,使用0是一种欺骗,但它确实起到了作用

 m.map( {case (s,c) => s.zipAll(Set(c),0,c)} ).flatten.toMap

像@Azzie,我在想zip,但也许Azzie在这些Zee上有优势

scala> val m = Map( Set(1, 2, 3) -> 'A', Set(4, 5, 6) -> 'B')
m: scala.collection.immutable.Map[scala.collection.immutable.Set[Int],Char] = Map(Set(1, 2, 3) -> A, Set(4, 5, 6) -> B)

scala> (m map { case (k, v) => k zip (Stream continually v) }).flatten.toMap
res0: scala.collection.immutable.Map[Int,Char] = Map(5 -> B, 1 -> A, 6 -> B, 2 -> A, 3 -> A, 4 -> B)

scala> (m map { case (k, v) => k zipAll (Nil, null, v) }).flatten.toMap
res1: scala.collection.immutable.Map[Any,Char] = Map(5 -> B, 1 -> A, 6 -> B, 2 -> A, 3 -> A, 4 -> B)

scala> m flatMap { case (k, v) => k zip (Stream continually v) }
res2: scala.collection.immutable.Map[Int,Char] = Map(5 -> B, 1 -> A, 6 -> B, 2 -> A, 3 -> A, 4 -> B)
现在还不清楚如何很好地概括它。

因为我显然有一种“可怕的泛型含义”:


实际上我有这个表单,但我在这里发布之前将它更改为
,以便理解,因为它更可读
我将其转换为一个
,用于理解。@toto2将更新为更好的版本,用于理解,当我真的不需要一直忘记流时,你的正在调用地图等。他们有什么开销需要担心吗?
scala> val m = Map( Set(1, 2, 3) -> 'A', Set(4, 5, 6) -> 'B')
m: scala.collection.immutable.Map[scala.collection.immutable.Set[Int],Char] = Map(Set(1, 2, 3) -> A, Set(4, 5, 6) -> B)

scala> (m map { case (k, v) => k zip (Stream continually v) }).flatten.toMap
res0: scala.collection.immutable.Map[Int,Char] = Map(5 -> B, 1 -> A, 6 -> B, 2 -> A, 3 -> A, 4 -> B)

scala> (m map { case (k, v) => k zipAll (Nil, null, v) }).flatten.toMap
res1: scala.collection.immutable.Map[Any,Char] = Map(5 -> B, 1 -> A, 6 -> B, 2 -> A, 3 -> A, 4 -> B)

scala> m flatMap { case (k, v) => k zip (Stream continually v) }
res2: scala.collection.immutable.Map[Int,Char] = Map(5 -> B, 1 -> A, 6 -> B, 2 -> A, 3 -> A, 4 -> B)
import scala.collection.MapLike
import scala.collection.TraversableLike
import scala.collection.generic.CanBuildFrom

implicit class Map_[
  A,
  B,
  T1 : ({type L[X] = X => TraversableLike[A, T2]})#L,
  T2,
  M1 : ({type L[X] = X => MapLike[T1, B, M2]})#L, 
  M2 <: MapLike[T1, B, M2] with Map[T1, B]
](map: M1) {

  def fuse[M3](implicit cbfM: CanBuildFrom[M2, (A, B), M3]) : M3 =
    map.flatMap({ case (k, v) => k.toTraversable.map((_, v)) })
}
scala> Map(Set(1, 2, 3) -> 'A', Set(4, 5, 6) -> 'B').fuse
res: scala.collection.immutable.Map[Int,Char] =
     Map(5 -> B, 1 -> A, 6 -> B, 2 -> A, 3 -> A, 4 -> B)

scala> Map(Array(1, 2, 3) -> 'A', Array(4, 5, 6) -> 'B').fuse
res: scala.collection.immutable.Map[Int,Char] =
     Map(5 -> B, 1 -> A, 6 -> B, 2 -> A, 3 -> A, 4 -> B)