展平集合映射

tot*_*to2 5 scala

我试图展平一个地图,其中键是可遍历的,从某种意义上说:

Map( Set(1, 2, 3) -> 'A', Set(4, 5, 6) -> 'B')
Run Code Online (Sandbox Code Playgroud)

应该扁平化为:

Map(5 -> B, 1 -> A, 6 -> B, 2 -> A, 3 -> A, 4 -> B)
Run Code Online (Sandbox Code Playgroud)

这是我所做的:

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
}   
Run Code Online (Sandbox Code Playgroud)

有用。但:

  1. 有没有更简单的方法来做到这一点?

  2. 我对 Scala 类型系统不是很满意,我相信这可以改进。每当我使用我的函数时,我都必须明确指定类型:

    val map2 = Map( Set(1, 2, 3) -> 'A', Set(4, 5, 6) -> 'B')
    val fused2 = fuse[Int, Char, Set[Int]](map2)
    
    val map1: Map[Traversable[Int], Char] = Map( Set(1, 2, 3) -> 'A', Set(4, 5, 6) -> 'B')
    val fused1 = fuse[Int, Char, Traversable[Int]](map1)
    
    Run Code Online (Sandbox Code Playgroud)

PS:fuse当key traversables有非空交集时,这个函数没有多大意义。

som*_*ytt 2

就像@Azzie 一样,我也在考虑 zip,但也许 Azzie 在这些 zees 方面有优势。

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)
Run Code Online (Sandbox Code Playgroud)

如何很好地概括它并不明显。