简体   繁体   English

一般扩展Scala集合

[英]Generically extending Scala collections

I have a Seq[(A, B)] . 我有一个Seq[(A, B)] I wanted to add an implicit method to such collections so I can do .toMultiMap to get back a Map[A, Seq[B]] . 我想向此类集合添加隐式方法,以便可以执行.toMultiMap以获取Map[A, Seq[B]]

This was my first attempt: 这是我的第一次尝试:

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

But, now the problem is I always get back a Traversable for the values. 但是,现在的问题是,我总是会为这些值返回一个Traversable I want to get back a Map[A, Set[B]] if I do Set[(A, B)].toMultiMap . 如果要执行Set[(A, B)].toMultiMap我想找回Map[A, Set[B]]

So, then I tried something like this: 所以,然后我尝试了这样的事情:

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

But, it does not work: 但是,它不起作用:

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

What is the way to do this? 这是怎么做的?

I think this might be what you're after. 我认为这可能是您所追求的。

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

This passes a few simple tests: 这通过了一些简单的测试:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM