0

If I have

List((1,2),(1,3),(1,4))

and want to convert it to

List((1,List(2,3,4))

I do

val list = List((1, 2), (1, 3), (1, 4))

val groups = list groupBy { case (a, b) => a }

val tups = groups map { case ((a), list) => (a, list.map(_._2)) }
tups.toList

which works but trying to see if there is any other (better) way?

elm
  • 20,117
  • 14
  • 67
  • 113
user2066049
  • 1,371
  • 1
  • 12
  • 26
  • 3
    I think that's about as simple as it can get – Gangstead Sep 16 '14 at 04:27
  • see [how-to-build-a-multimap-from-a-list-of-tuples-in-scala](http://stackoverflow.com/questions/7209807/how-to-build-a-multimap-from-a-list-of-tuples-in-scala) – roterl Sep 16 '14 at 07:21

2 Answers2

1

A little simpler, maybe, and does it in one pass:

  val list = List((1, 2), (1, 3), (1, 4), (2, 5), (2, 6))

  list.foldRight(Map[Int,List[Int]]()) { case ((k, v), m) =>
       m updated (k, v :: (m getOrElse (k, Nil))) }

  //> res1: scala.collection.immutable.Map[Int,List[Int]] = Map(2 -> List(5, 6), 1
  //|  -> List(2, 3, 4))

My codegolf entry (a variant of Vladimir's, but shorter):

list.groupBy(_._1).mapValues(_.unzip._2)  
The Archetypal Paul
  • 41,321
  • 20
  • 104
  • 134
1

I believe this is as short as it can possibly get:

scala> val l = List((1, 2), (1, 3), (1, 4))
l: List[(Int, Int)] = List((1,2), (1,3), (1,4))

scala> l.groupBy(_._1).mapValues(_.map(_._2)).toList
res0: List[(Int, List[Int])] = List((1,List(2, 3, 4)))

It does require several passes though, but for small to medium-sized lists it doesn't really matter.

Vladimir Matveev
  • 120,085
  • 34
  • 287
  • 296