2013-07-28 13 views
11

Prima di tutto, ci scusiamo per la domanda zoppa. Sto leggendo la `Scala per l'Impaziente' religiosamente e cercando di risolvere tutte le questioni di esercizio (e fare un po' di esplorazione minima)Uso della funzione `map` su Map in Scala

Background: La domanda esercizio va come - Imposta una mappa dei prezzi per un certo numero di aggeggi che brami. Quindi produrre una seconda mappa con le stesse chiavi e i prezzi con uno sconto del 10%.

Purtroppo, a questo punto, la maggior parte delle parti del scaladoc sono ancora criptico per me, ma ho capito che la funzione mappa della Map prende una funzione e restituisce un'altra mappa dopo l'applicazione di una funzione (suppongo?) - def map[B](f: (A) ⇒ B): HashMap[B]. Ho provato googling ma poteva ottenere risultati molto utili per map function for Map in scala :-)

La mia domanda: Come tentato nel mio variante 3, non utilizzando la funzione map per questo scopo ha alcun senso o dovrei attaccare con la variante 2 che in realtà risolve il mio problema.

Codice:

val gizmos:Map[String,Double]=Map("Samsung Galaxy S4 Zoom"-> 1000, "Mac Pro"-> 6000.10, "Google Glass"->2000) 

//1. Normal for/yield 
val discountedGizmos=(for ((k,v)<-gizmos) yield (k, v*0.9)) //Works fine 

//2. Variation using mapValues 
val discGizmos1=gizmos.mapValues(_*0.9) //Works fine 

//3. Variation using only map function 
val discGizmos2=gizmos.map((_,v) =>v*0.9) //ERROR : Wrong number of parameters: expected 1 

risposta

15

In questo caso, mapValues ​​sembra il metodo più appropriato da utilizzare. Dovresti utilizzare il metodo mappa quando è necessario eseguire una trasformazione che richiede la conoscenza delle chiavi (ad esempio, la conversione di un riferimento prodotto in un nome prodotto, ad esempio).

Detto questo, il metodo mappa è più generale in quanto consente di accedere sia alle chiavi che ai valori su cui si può agire, e si può emulare il metodo mapValues ​​semplicemente trasformando i valori e passando le chiavi in ​​modo intatto - e è qui che stai sbagliando nel tuo codice qui sopra. Per utilizzare il metodo mappa correttamente, si dovrebbe essere la produzione di un (valore chiave,) coppia da una funzione, non solo una chiave:

val discGizmos2=gizmos.map{ case (k,v) => (k,v*0.9) } // pass the key through unchanged 
+0

Wow. Questo ha perfettamente senso. Grazie mille per aver dedicato del tempo a spiegarti chiaramente. –

+1

Vale la pena notare che 'mapValues' crea una vista sulla mappa esistente mentre' map' crea un'intera nuova mappa. – Daenyth

4

Può essere anche:

val discGizmos2 = gizmos.map(kv => (kv._1, kv._2*0.9)) 
+0

Bello. Adoro il modo in cui Scala ti consente di fare la stessa cosa in più di un modo. Grazie !! –

+0

questo è equivalente all'utilizzo di una tupla ... cioè, kv è semplicemente una tupla. – piyushGoyal