2010-02-03 12 views
22

Tengo dos listas, una List[A] y una List[B]. Lo que quiero es un Map[A,B] pero quiero la semántica de zip. Así que empecé a cabo de esta manera:En Scala, ¿hay alguna manera de convertir dos listas en un mapa?

var tuplesOfAB = listOfA zip listOfB 

Ahora no estoy seguro de cómo construir una Map de mi tuplesOfAB.

Como una pregunta de seguimiento, también quiero invertir mi mapa para que a partir de un Map[A,B] puedo crear un Map[B,A]. ¿Alguien puede golpearme con una pista de palo?

+1

Gracias por preguntar esto. Vine aquí para encontrarlo. Ahora no tengo que preguntarlo yo mismo. – wheaties

Respuesta

26

En 2,8 esto es realmente simple usando la funcionalidad CanBuildFrom (as described by Daniel) y el uso de breakOut con un tipo instrucción al compilador cuanto a lo que debe ser el tipo de resultado:

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

lo siguiente sería también funciona:

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

Y (como EastSun, a continuación, ha señalado) esto se ha agregado a la biblioteca como toMap

val o = (listA zip listB).toMap 

En cuanto a revertir el mapa, se puede hacer:

val r = m.map(_.swap)(breakOut): Map[B, A] 
+4

val m = (listA zip listB) toMap también funciona en scala 2.8 – Eastsun

+0

¡Ah! Ese método no existe en la compilación de 2.8 que tengo (r20327) –

+1

sí, se agregó recientemente después de que paulp haya demostrado lo fácil que era escribirlo, en respuesta a otra pregunta. Luego sugirió agregarlo a la lib, ya que todas las otras colecciones principales ya estaban representadas. –

15

Ahora que tiene una lista de tuplas, es fácil hacerlo en un mapa escribiendo Map(tuplesOfAB: _*). La notación : _* significa llamar a la sobrecarga varargs con los argumentos tomados de la secuencia. Esto parece un poco gracioso de sintaxis, pero ayuda a pensar que varargs se declaran como Map[A,B](pairs: (A,B)*) y : _* es una anotación de tipo para convertir a varargs debido a la parte * común.

Para invertir un mapa m use Map(m.map(_.swap): _*). En Scala, un mapa también es una colección de pares. Esto transforma esos pares intercambiando los elementos y pasándolos al constructor del Mapa.

+0

¡Eso es hermoso, gracias! –

5

Hay otra manera de hacerlo, más allá de las que se muestran. Aquí:

Map() ++ tuplesOfAB 
4
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) 
Cuestiones relacionadas