4

I tried to group a list of tuples in Scala.

The input:

val a = List((1,"a"), (2,"b"), (3,"c"), (1,"A"), (2,"B"))

I applied:

a.groupBy(e => e._1)

The output I get is:

Map[Int,List[(Int, String)]] = Map(2 -> List((2,b), (2,B)), 1 -> List((1,a), (1,A)), 3 -> List((3,c)))

This is slightly different with what I expect:

Map[Int,List[(Int, String)]] = Map(2 -> List(b, B), 1 -> List(a, A)), 3 -> List(c))

What can I do to get the expected output?

Andrey Tyukin
  • 43,673
  • 4
  • 57
  • 93
ZZZ
  • 645
  • 4
  • 17
  • Surprisingly, not a duplicate of [this here](https://stackoverflow.com/questions/42871691/scala-how-to-merge-lists-by-the-first-element-of-the-tuple), the accepted answer exactly *does not* answer the actual question. – Andrey Tyukin May 20 '18 at 22:18

2 Answers2

4

You probably meant something like this:

a.groupBy(_._1).mapValues(_.map(_._2))

or:

a.groupBy(_._1).mapValues(_.unzip._2)

Result:

Map(2 -> List(b, B), 1 -> List(a, A), 3 -> List(c))
Andrey Tyukin
  • 43,673
  • 4
  • 57
  • 93
  • Thanks. This works for my purpose. Is there another way to apply groupBy to avoind using the mapValues? – ZZZ May 20 '18 at 22:19
  • 1
    @ZZZ Since `groupBy` on `List[A]` will return `Map[K, List[A]]`, there seems to be no way around it, because `List[(X, Y)]` will always be transformed into a `Map[K, List[(X, Y)]]` instead of `Map[K, List[Y]]`. So, no, you have to `mapValues`. I've added another, hopefully more aesthetically pleasing variant. – Andrey Tyukin May 20 '18 at 22:23
0

If you do not want to use mapValues, is this what you are expecting?

 a.groupBy(_._1).map(f => (f._1, f._2.map(_._2)))

Result

Map(2 -> List(b, B), 1 -> List(a, A), 3 -> List(c))