29

I have a two lists, a List[A] and a List[B]. What I want is a Map[A,B] but I want the semantics of zip. So started out like so:

var tuplesOfAB = listOfA zip listOfB

Now I'm not sure how to construct a Map from my tuplesOfAB.

As a follow-up question, I also want to invert my map so that from a Map[A,B] I can create a Map[B,A]. Can anyone hit me with a clue-stick?

oxbow_lakes
  • 133,303
  • 56
  • 317
  • 449
Andy Hull
  • 1,843
  • 2
  • 14
  • 16

4 Answers4

38

In 2.8 this is really simple using the CanBuildFrom functionality (as described by Daniel) and using breakOut with a type instruction to the compiler as to what the result type should be:

import scala.collection.breakOut
val m = (listA zip listB)(breakOut): Map[A,B]

The following would also work:

val n: Map[A,B] = (listA zip listB)(breakOut)

And (as EastSun, below, has pointed out) this has been added to the library as toMap

val o = (listA zip listB).toMap

As for reversing the map, you can do:

val r = m.map(_.swap)(breakOut): Map[B, A]
Community
  • 1
  • 1
oxbow_lakes
  • 133,303
  • 56
  • 317
  • 449
  • Ah! That method does not exist in the build of 2.8 which I have (r20327) – oxbow_lakes Feb 03 '10 at 10:48
  • 1
    yes, it was recently added after paulp has shown how easy it was to write it, in response to another question. He then suggested adding it to the lib, since every other major collection was already represented. – Daniel C. Sobral Feb 03 '10 at 11:41
15

Now that you've got a list of tuples it is easy to make it into a map by writing Map(tuplesOfAB: _*). The : _* notation means to call the varargs overload with the arguments taken from the sequence. This seems like a funny bit of syntax, but it helps to think that varargs are declared like Map[A,B](pairs: (A,B)*) and the : _* is a type annotation to convert to varargs because of the common * part.

To reverse a map m use Map(m.map(_.swap): _*). In scala a map is also a collection of pairs. This transforms those pairs by swapping the elements and passing them to the Map constructor.

Geoff Reedy
  • 34,891
  • 3
  • 56
  • 79
6
scala> List( "a", "f", "d") zip List(7, 5, 4, 8) toMap
res0: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 7, f -> 5, d -> 4)
Sudheer Aedama
  • 2,116
  • 2
  • 21
  • 39
Ashwin
  • 445
  • 5
  • 9
6

There's yet another way to do it, beyond those already shown. Here:

Map() ++ tuplesOfAB
Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681