scala - tokio - ¿Cómo convertir una Seq[A] a un Mapa[Int, A] usando un valor de A como la clave en el mapa?
mapa madrid turistico (4)
Tengo un Seq
contiene objetos de una clase que se parece a esto:
class A (val key: Int, ...)
Ahora quiero convertir este Seq
a un Map
, usando el valor key
de cada objeto como la clave, y el objeto en sí mismo como el valor. Asi que:
val seq: Seq[A] = ...
val map: Map[Int, A] = ... // How to convert seq to map?
¿Cómo puedo hacerlo de manera eficiente y elegante en Scala 2.8?
Como Scala sabe convertir una Tupla de dos en un mapa, primero deberías convertir tu seq a una tupla y luego asignarla a un mapa (no importa si es int, en nuestra cadena de casos, cadena):
El algoritmo general es este:
- Para cada artículo en Seq
- Artículo -> Tuple (clave, valor)
- Para cada tupla (clave, valor)
- Agregar al mapa (clave, valor)
O para resumir:
Paso 1: Seq -> Tuple de dos
Paso 2: Tupla de dos -> Mapa
Ejemplo:
case class MyData(key: String, value: String) // One item in seq to be converted to a map entry.
// Our sequence, simply a seq of MyData
val myDataSeq = Seq(MyData("key1", "value1"), MyData("key2", "value2"), MyData("key3", "value3")) // List((key1,value1), (key2,value2), (key3,value3))
// Step 1: Convert seq to tuple
val myDataSeqAsTuple = myDataSeq.map(myData => (myData.key, myData.value)) // List((key1,value1), (key2,value2), (key3,value3))
// Step 2: Convert tuple of two to map.
val myDataFromTupleToMap = myDataSeqAsTuple.toMap // Map(key1 -> value1, key2 -> value2, key3 -> value3)
Desde 2.8 Scala ha tenido .toMap
, así que:
val map = seq.map(a => a.key -> a).toMap
o si te gusta mucho evitar evitar construir una secuencia intermedia de tuplas:
val map: Map[Int, A] = seq.map(a => a.key -> a)(collection.breakOut)
Mapa sobre su Seq
y producir una secuencia de tuplas. Luego usa esas tuplas para crear un Map
. Funciona en todas las versiones de Scala.
val map = Map(seq map { a => a.key -> a }: _*)
Una variación más de 2.8, en buena medida, también eficiente:
scala> case class A(key: Int, x: Int)
defined class A
scala> val l = List(A(1, 2), A(1, 3), A(2, 1))
l: List[A] = List(A(1,2), A(1,3), A(2,1))
scala> val m: Map[Int, A] = (l, l).zipped.map(_.key -> _)(collection.breakOut)
m: Map[Int,A] = Map((1,A(1,3)), (2,A(2,1)))
Tenga en cuenta que si tiene claves duplicadas, ¡descartará algunas de ellas durante la creación del mapa! Puede usar groupBy
para crear un mapa donde cada valor es una secuencia:
scala> l.groupBy(_.key)
res1: scala.collection.Map[Int,List[A]] = Map((1,List(A(1,2), A(1,3))), (2,List(A(2,1))))