2012-02-16 8 views
36

LinkedHashMap se utiliza para conservar el orden de inserción en el mapa, pero esto solo funciona para mapas mutables. ¿Cuál es la implementación inmutable de Map que preserva el orden de inserción?Implementación inamovible de Scala Map que conserva el orden de inserción

+1

Esto no es un duplicado exacto, la pregunta es para el mapa inmutable, el supuesto duplicado es sobre ambos mutable e inmutable. la otra pregunta no * directamente * responde a la parte inmutable (tal vez lo hace de manera indirecta) –

Respuesta

41

ListMap implementa un mapa inmutable utilizando una estructura de datos basada en listas, y así conserva el orden de inserción.

scala> import collection.immutable.ListMap 
import collection.immutable.ListMap 

scala> ListMap(1 -> 2) + (3 -> 4) 
res31: scala.collection.immutable.ListMap[Int,Int] = Map(1 -> 2, 3 -> 4) 

scala> res31 + (6 -> 9) 
res32: scala.collection.immutable.ListMap[Int,Int] = Map(1 -> 2, 3 -> 4, 6 -> 9) 

El siguiente método de extensión - Seq#toListMap pueden ser muy útiles cuando se trabaja con ListMap s.

scala> import scalaz._, Scalaz._, Liskov._ 
import scalaz._ 
import Scalaz._ 
import Liskov._ 

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

implicit def seqW[A](xs: Seq[A]) = new SeqW(xs) 
class SeqW[A](xs: Seq[A]) { 
    def toListMap[B, C](implicit ev: A <~< (B, C)): ListMap[B, C] = { 
    ListMap(co[Seq, A, (B, C)](ev)(xs) : _*) 
    } 
} 


// Exiting paste mode, now interpreting. 

seqW: [A](xs: Seq[A])SeqW[A] 
defined class SeqW 

scala> Seq((2, 4), (11, 89)).toListMap 
res33: scala.collection.immutable.ListMap[Int,Int] = Map(2 -> 4, 11 -> 89) 
+1

Hay un problema con ListMap - actualización de llamada() con la clave * cambios * existentes en el orden de los elementos. Ejemplo: 'ListMap (" a "→ 1," b "→ 2) .updated (" a ", 2) .toList' produce' List ((b, 2), (a, 2)) '. Muy desafortunado para mi caso de uso :( –

20

Mientras ListMap se preservar el orden de inserción, no es muy eficiente - por ejemplo, el tiempo de búsqueda es lineal. Le sugiero que cree una nueva clase de colección que incluya tanto el immutable.HashMap como el immutable.TreeMap. El mapa inmutable debe parametrizarse como immutable.HashMap[Key, (Value, Long)], donde Long en la tupla le proporciona el puntero a la entrada correspondiente en el TreeMap[Long, Key]. A continuación, mantenga un contador de entrada en el lateral. Este mapa de árbol ordenará las entradas de acuerdo con el orden de inserción.

Implementa la inserción y la búsqueda de la manera directa: incremente el contador, inserte en el mapa hash e inserte en el par de contra-teclas en el mapa de árbol. Utiliza el mapa hash para la búsqueda.

Implementa la iteración usando el mapa de árbol.

Para implementar eliminar, debe eliminar el par de clave-valor del mapa de hash y usar el índice de la tupla para eliminar la entrada correspondiente del mapa de árbol.

+3

+1. ¿Alguna posibilidad de tener tal colección en stdlib en un futuro próximo? – missingfaktor

+0

Esto no ha sido planeado, pero si la discusión en la lista de correo de Scala internals reveló que mucha gente quiere esto , entonces por qué no. – axel22

+1

¿Le importaría explicar por qué? – axel22

Cuestiones relacionadas