1

私は持っていSeq[(A, B)]ます。.toMultiMapそのようなコレクションに暗黙的なメソッドを追加して、 を取得できるようにしたかったのMap[A, Seq[B]]です。

これは私の最初の試みでした:

  implicit class PairsExtensions[A, B](t: Traversable[(A, B)]) {
    def toMultiMap: Map[A, Traversable[B]] = t.groupBy(_._1).mapValues(_.map(_._2))
  }

しかし、今の問題はTraversable、値に対して常に a が返されることです。Map[A, Set[B]]もしそうなら、私は元に戻したいですSet[(A, B)].toMultiMap

それで、私は次のようなことを試しました:

 implicit class PairsExtensions2[A, B, Repr[_] <: Traversable[(A, B)]](t: TraversableLike[(A, B), Repr[(A, B)]]) {
    def toMultiMap(implicit bf: CanBuild[B, Repr[B]]): Map[A, Repr[B]] = t.groupBy(_._1).mapValues(_.map(_._2))
  }

しかし、それは機能しません:

val m1: Map[Int, Set[String]] = Set.empty[(Int, String)]
val m2: Map[Int, List[String]] = List.empty[(Int, String)]

これを行う方法は何ですか?

4

1 に答える 1

4

これはあなたが求めているものかもしれないと思います。

import scala.collection.generic.CanBuildFrom
import scala.language.higherKinds

implicit class PairsExtensions[A, B, C[X] <: Traversable[X]](t: C[(A, B)]) {
  def toMultiMap(implicit cbf: CanBuildFrom[Nothing, B, C[B]]): Map[A, C[B]] =
    t.groupBy(_._1).mapValues(_.map(_._2).to[C])
}

これは、いくつかの簡単なテストに合格します。

scala> val m1: Map[Int, Set[String]] = Set.empty[(Int, String)].toMultiMap
m1: Map[Int,Set[String]] = Map()

scala> val m2: Map[Int, List[String]] = List.empty[(Int, String)].toMultiMap
m2: Map[Int,List[String]] = Map()

scala> Seq(('c',4),('x',2),('c',5)).toMultiMap
res4: Map[Char,Seq[Int]] = Map(x -> Vector(2), c -> Vector(4, 5))
于 2016-03-22T02:29:04.227 に答える