Si tengo una colección cde tipos Ty hay una propiedad pen T(de tipo P, por ejemplo), ¿cuál es la mejor manera de hacer una clave de mapa por extracción ?
val c: Collection[T]
val m: Map[P, T]
Una forma es la siguiente:
m = new HashMap[P, T]
c foreach { t => m add (t.getP, t) }
Pero ahora necesito un mapa mutable . ¿Hay una mejor manera de hacer esto para que esté en 1 línea y termine con un Mapa inmutable ? (Obviamente, podría convertir lo anterior en una simple utilidad de biblioteca, como lo haría en Java, pero sospecho que en Scala no hay necesidad)
scala
map
scala-collections
oxbow_lakes
fuente
fuente

Traversable[K].mapTo( K => V)yTraversable[V].mapBy( V => K)fueron mejores!cconc.iteratorpara evitar la creación de una colección intermedia.Puede construir un mapa con un número variable de tuplas. Por lo tanto, use el método de mapa en la colección para convertirlo en una colección de tuplas y luego use el truco: _ * para convertir el resultado en un argumento variable.
fuente
Además de la solución de @James Iry, también es posible lograr esto usando un pliegue. Sospecho que esta solución es un poco más rápida que el método de tupla (se crean menos objetos basura):
fuente
list.foldLeft(Map[String,Int]()) { (m,s) => m + (s -> s.length) }. Tenga en cuenta que si quieres usar una coma para construir la tupla, necesita un par adicional de paréntesis:((s, s.length)).Esto se puede implementar de manera inmutable y con un solo recorrido al plegar la colección de la siguiente manera.
La solución funciona porque agregar a un Mapa inmutable devuelve un nuevo Mapa inmutable con la entrada adicional y este valor sirve como acumulador a través de la operación de plegado.
La desventaja aquí es la simplicidad del código versus su eficiencia. Por lo tanto, para colecciones grandes, este enfoque puede ser más adecuado que usar 2 implementaciones transversales como la aplicación
mapytoMap.fuente
Otra solución (puede que no funcione para todos los tipos)
esto evita la creación de la lista de intermediarios, más información aquí: Scala 2.8 breakOut
fuente
Lo que estás tratando de lograr es un poco indefinido.
¿Qué pasa si dos o más elementos
ccomparten lo mismop? ¿Qué elemento se asignará a esopen el mapa?La forma más precisa de ver esto es generar un mapa entre
py todos loscelementos que lo tienen:Esto podría lograrse fácilmente con groupBy :
Si aún desea el mapa original, puede, por ejemplo, asignar
pal primerotque lo tiene:fuente
collectlugar demap. Por ejemplo:c.group(t => t.p) collect { case (Some(p), ts) => p -> ts.head }. De esta forma, puede hacer cosas como aplanar mapas cuando la tecla es una Opción [_]..mapValues(_.head)lugar del mapa.Probablemente esta no sea la forma más eficiente de convertir una lista en un mapa, pero hace que el código de llamada sea más legible. Usé conversiones implícitas para agregar un método mapBy a List:
Ejemplo de código de llamada:
Tenga en cuenta que debido a la conversión implícita, el código de la persona que llama necesita importar las conversiones implícitas de scala.
fuente
Funciona bien y es muy intuitivo.
fuente
ccomo clave (más o menos). Tenga en cuenta "map" porque la colección resultante no es una escalaMapsino que crea otra lista / iterable de tuplas ... pero el efecto es el mismo para el propósito del OP, no descartaría la simplicidad pero no es tan eficiente como lafoldLeftsolución, ni es la verdadera respuesta a la pregunta "convertir en una colección en un mapa por clave"¿Qué tal usar zip y toMap?
fuente
Por lo que vale, aquí hay dos formas inútiles de hacerlo:
fuente
Map.fromList $ map (bar &&& id) c,Map.fromList $ map (bar >>= (,)) c.Esto funciona para mi:
El mapa debe ser mutable y el mapa debe ser devuelto ya que agregarlo a un mapa mutable no devuelve un mapa.
fuente
val personsMap = persons.foldLeft(Map[Int, PersonDTO]()) { (m, p) => m + (p.id -> p) }el mapa puede ser inmutable, como se evidencia anteriormente, porque al agregarlo a un mapa inmutable, se devuelve un nuevo mapa inmutable con la entrada adicional. Este valor sirve como acumulador a través de la operación de plegado.use map () en la colección seguido de toMap
fuente
Si se convierte de Json String (leyendo un archivo json) a Scala Map
fuente