2011-08-09 17 views
23

Ho una mappa che devo mappare a un tipo diverso e il risultato deve essere una lista. Ho due modi (apparentemente) per realizzare ciò che voglio, dal momento che chiamare la mappa su una mappa sembra sempre risultare in una mappa. Supponendo che ho qualche mappa che assomiglia:Conversione di una mappa Scala in una lista

val input = Map[String, List[Int]]("rk1" -> List(1,2,3), "rk2" -> List(4,5,6)) 

posso neanche fare:

val output = input.map{ case(k,v) => (k.getBytes, v) } toList 

Oppure:

val output = input.foldRight(List[Pair[Array[Byte], List[Int]]]()){ (el, res) => 
    (el._1.getBytes, el._2) :: res 
} 

Nel primo esempio si converte il tipo, e quindi chiamare toList . Presumo che il runtime è qualcosa come O(n*2) e lo spazio richiesto è n*2. Nel secondo esempio, converto il tipo e generi la lista in un colpo solo. Presumo che il runtime sia O(n) e lo spazio richiesto sia n.

La mia domanda è, sono sostanzialmente identici o la seconda conversione è ridotta alla memoria/ora/ecc.? Inoltre, dove posso trovare informazioni sui costi di archiviazione e runtime di varie scale conversion?

Grazie in anticipo.

risposta

23

mio modo preferito per fare questo genere di cose è come questo:

input.map { case (k,v) => (k.getBytes, v) }(collection.breakOut): List[(Array[Byte], List[Int])] 

Con questa sintassi, si passa al map il costruttore ha bisogno di ricostruire la collezione risultante. (In realtà, non un costruttore, ma una fabbrica di costruttori.Per maggiori informazioni su Scala CanBuildFrom s se sei interessato.) collection.breakOut può essere utilizzato esattamente quando si desidera passare da un tipo di raccolta a un altro mentre si fa un map, flatMap, ecc. l'unica cosa brutta è che devi usare l'annotazione completa del tipo perché sia ​​efficace (qui, ho usato un attributo di tipo dopo l'espressione). Quindi, non viene creata alcuna raccolta intermedia e viene creato l'elenco mentre la mappatura.

+3

+1. Per coloro che cercano di capire come funziona 'breakOut', vedere l'eccellente risposta di Daniel Sobral, http://stackoverflow.com/questions/1715681/scala-2-8-breakout/1716558#1716558 –

18

Mapping su una vista nel primo esempio potrebbe ridurre gli ingombri di una mappa grande:

val output = input.view.map{ case(k,v) => (k.getBytes, v) } toList 
+0

Informazioni sulle visualizzazioni lazy: http: // www .scala-lang.org/docu/files/collezioni-api/collections_42.html – Vadzim

Problemi correlati