1

我有一个我正在调用 groupBy 的 Pairs 列表。但是, groupBy 在值中包含该对的两个部分,我只想包含该对中未“分组依据”的部分。

List(1->2, 1->3, 2->3) groupBy (_._1)

scala.collection.immutable.Map[Int,List[(Int, Int)]] = Map(1 -> List((1,2), (1,3)), 2 -> List((2,3) ))

我写了一个方法来映射 Map 条目并删除重复键:

def removeDupeKeyFromPair[A, B](m: Map[A, List[Pair[A, B]]]): Map[A, List[B]] =
  m map { case(k, vlist) => k -> { vlist map { case(dupe, b) => b } } }

但是,我想将其概括List[Pair[A,B]]C[Pair[A,B]]where C<:Iterable,所以我尝试了

def removeDupeKeyFromPair[A, B, C[Pair[A, B]] <: Iterable[Pair[A, B]]]
                         (m: Map[A, C[Pair[A, B]]]): Map[A, C[B]]

但这产生了

错误:B 没有类型参数,预期:两个

如何正确表达这些类型?

编辑: 这对我来说是一个学习练习,所以我对如何正确表达给定类型更感兴趣,而不是寻找另一个解决方案。尽管了解其他解决方案也很棒。

4

3 回答 3

3

如果您只想更改Map值,可以使用mapValues

scala> List(1->2, 1->3, 2->3) groupBy (_._1) mapValues (_.map(_._2))
res2: scala.collection.immutable.Map[Int,List[Int]] = Map(2 -> List(3), 1 -> List(2, 3))

或者以更易读的方式:

scala> List(1->2, 1->3, 2->3) groupBy (_._1) mapValues (lst => lst.map { case(_ ,b) => b })
res3: scala.collection.immutable.Map[Int,List[Int]] = Map(2 -> List(3), 1 -> List(2, 3))
于 2013-02-13T16:57:52.410 回答
1

为了使这些更通用,您可以使用专门的类型类。用于 和 等方法的map方法flatMapFilterMonadic

FilterMonadic将其 map 方法指定为使用CanBuildFrom. 大多数内置集合类都有其中一个可用。然后你可以像这样使用它:

def removeDupeKeyFromPair[A, B, 
  // Define a type C that has type arguments and extends FilterMonadic
  C[X] <: FilterMonadic[X, C[X]], 
  // Define the type that will be returned (provided by the implicit CanBuildFrom)
  That](
    // Use C instead of List    
    m: Map[A, C[(A, B)]])(
      // Define the CanBuildFrom that is required by the map method
      implicit bf:CanBuildFrom[C[(A, B)], B, That]): Map[A, That] =

        // actual logic
        m.map { case (k, vlist) =>
          k -> vlist.map { case (dupe, b) => b }
        }

编辑

请注意,我使用了(A, B)符号而不是Pair[A, B]

于 2013-02-13T19:32:32.920 回答
1

使用有什么意义C<:Iterable

如果你定义:

def removeDupeKeyFromPair[A,B](m: Map[A, Iterable[(A,B)]]) : Map[A, Iterable[B]]=
      m map { case(k, vlist) => k -> { vlist map { case(dupe, b) => b } } }

并在列表上调用该方法,它将返回一个Map[A, List[B]]. 这是由于Builderscala 集合中的机制。

于 2013-02-13T18:05:05.067 回答