Как написать обобщенный c groupByKey для Traversable [(K, V)] в scala <= 2.12 - PullRequest
1 голос
/ 30 января 2020

Довольно просто написать функцию от 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))

, но, к сожалению, это спецификация типа коллекции c.

Я могу обобщить это, конечно,

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

, но теперь я получил Traversable назад, и я бы очень хотел, чтобы тот же тип, который я вставил, так как groupBy делает это для меня.

1 Ответ

1 голос
/ 30 января 2020

Разобрался.

Как метод:

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))

Как неявный класс:

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))
}
...