如何在 scala <= 2.12 中为 Traversable[(K, V)] 编写通用 groupByKey

How do I write a generic groupByKey for a Traversable[(K, V)] in scala <= 2.12

写一个从 List[(K, V)]Map[K, List[V]] 的函数非常容易:

def groupByKey[K, V](
  pairs: List[(K, V)]
): Map[K, List[V]] =
  pairs
    .groupBy(_._1)
    .mapValues(_.map(_._2))

但它是特定于集合类型的,这似乎很遗憾。

我当然可以概括为

def groupByKey[K, V](
  pairs: Traversable[(K, V)]
): Map[K, Traversable[V]] =
  pairs
    .groupBy(_._1)
    .mapValues(_.map(_._2))

但现在我有一个 Traversable 回来了,我非常喜欢我放入的相同类型,因为 groupBy 为我做了。

解决了。

作为方法:

def groupByKey[K, V, Repr <: TraversableLike[(K, V), Repr], That <: TraversableLike[V, That]](
  pairs: TraversableLike[(K, V), Repr]
)(implicit
  bf: CanBuildFrom[Repr, V, That]
): Map[K, That] = pairs
  .groupBy(_._1)
  .mapValues(_.map(_._2))

作为隐式 class:

implicit class GroupByKey[K, +V, +Repr <: TraversableLike[(K, V), Repr], +That <: TraversableLike[V, That]](
  decorated: TraversableLike[(K, V), Repr]
)(implicit
  bf: CanBuildFrom[Repr, V, That]
) {
  def groupByKey: Map[K, That] = decorated
    .groupBy(_._1)
    .mapValues(_.map(_._2))
}