2012-02-16 21 views
36

LinkedHashMap viene utilizzato per conservare l'ordine di inserimento nella mappa, ma funziona solo per mappe mutabili. Qual è l'implementazione immutabile Map che conserva l'ordine di inserimento?Implementazione di Scala Scala immutabile che conserva l'ordine di inserimento

+1

Questo non è un duplicato esatto, la domanda è per la mappa Immutabile, il presunto duplicato riguarda sia mutabile che immutabile. l'altra domanda non * direttamente * risponde alla parte immutabile (forse lo fa indirettamente) –

risposta

41

ListMap implementa una mappa immutabile utilizzando una struttura di dati basata su elenchi e quindi conserva l'ordine di inserimento.

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) 

Il seguente metodo di estensione - Seq#toListMap può essere molto utile quando si lavora 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

C'è un trucco con ListMap - chiamando update() con la chiave esistente * cambia * l'ordine degli articoli. Esempio: 'ListMap (" a "→ 1," b "→ 2) .updated (" a ", 2) .toList' restituisce' List ((b, 2), (a, 2)) '. Molto spiacevole per il mio caso d'uso :( –

20

Mentre ListMap conserveranno ordine di inserimento, non è molto efficiente - esempio il tempo di ricerca è lineare. Ti suggerisco di creare una nuova classe di raccolta che comprenda sia lo immutable.HashMap sia lo immutable.TreeMap. La mappa immutabile deve essere parametrizzata come immutable.HashMap[Key, (Value, Long)], dove lo Long nella tupla fornisce il puntatore alla voce corrispondente nello TreeMap[Long, Key]. Quindi tieni un contatore di entrata sul lato. Questa mappa albero ordinerà le voci in base all'ordine di inserimento.

Si implementa l'inserimento e la ricerca in modo diretto - incrementare il contatore, inserire nella mappa hash e inserire la coppia di chiavi in ​​chiave nella mappa dei tre. Si utilizza la mappa hash per la ricerca.

Si implementa l'iterazione utilizzando la mappa ad albero.

Per implementare la rimozione, è necessario rimuovere la coppia chiave-valore dalla mappa hash e utilizzare l'indice dalla tupla per rimuovere la voce corrispondente dalla mappa dell'albero.

+3

+1. Qualche possibilità di avere una tale collezione in stdlib nel prossimo futuro? – missingfaktor

+0

Questo non è stato pianificato, ma se la discussione sulla mailing list di Scala internals ha rivelato che molte persone lo vogliono – axel22

+1

Ti piacerebbe elaborare perché? – axel22

Problemi correlati