在scala中的GroupBy

use*_*411 5 scala

我有

val a = List((1,2), (1,3), (3,4), (3,5), (4,5))
Run Code Online (Sandbox Code Playgroud)

我正在使用A.groupBy(_._1)groupBy和第一个元素.但是,它给了我输出

Map(1 -> List((1,2) , (1,3)) , 3 -> List((3,4), (3,5)), 4 -> List((4,5)))
Run Code Online (Sandbox Code Playgroud)

但是,我想要回答

Map(1 -> List(2, 3), 3 -> List(4,5) , 4 -> List(5))
Run Code Online (Sandbox Code Playgroud)

那么,我该怎么做呢?

Sha*_*nds 9

你可以通过跟进mapValues(和map每个值来提取第二个元素)来做到这一点:

scala> a.groupBy(_._1).mapValues(_.map(_._2))
res2: scala.collection.immutable.Map[Int,List[Int]] = Map(4 -> List(5), 1 -> List(2, 3), 3 -> List(4, 5))
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`mapValues`是惰性的,因此每次您从生成的`Map`中访问值时都会调用`_.map(_._ 2)`。如果要避免这种情况,请使用`map {case(k,v)=> k-> v.map(_._ 2)}`。 (2认同)

Eas*_*sun 5

通过模式匹配使生活变得轻松和Map#withDefaultValue

scala> a.foldLeft(Map.empty[Int, List[Int]].withDefaultValue(Nil)){ 
         case(r, (x, y)) => r.updated(x, r(x):+y) 
       }
res0: scala.collection.immutable.Map[Int,List[Int]] = 
      Map(1 -> List(2, 3), 3 -> List(4, 5), 4 -> List(5))
Run Code Online (Sandbox Code Playgroud)

有两点:

  1. Map#withDefaultValue 将获得具有给定默认值的地图,那么您无需检查地图是否包含键。

  2. 当Scala中某个地方需要一个函数值时(x1,x2,..,xn) => y,您始终可以在case(x1,x2,..,xn) => y此处使用模式匹配,编译器会将其转换为auto函数。看看到8.5模式匹配匿名函数获取更多信息。

对不起,我英语不好。