2013-07-28 5 views
11

Zunächst einmal, Entschuldigung für die lahme Frage. Ich lese die `Scala für Ungeduldige‘ religiös und versuchen, alle Übungsfragen zu lösen (und einige minimale Exploration tun)Verwenden von `map` Funktion auf Karte in Scala

Hintergrund: Die Übung Frage geht wie - Setup-Karte Preise für eine Reihe von Gizmos, die Sie begehren. Dann erstellen Sie eine zweite Karte mit den gleichen Schlüsseln und die Preise mit einem Rabatt von 10%.

Leider zu diesem Zeitpunkt die meisten Teile des scaladoc sind mir noch kryptisch, aber ich verstehe, dass die Kartenfunktion der Map eine Funktion nimmt und eine andere Karte nach einer Funktion der Anwendung (ich glaube?) - def map[B](f: (A) ⇒ B): HashMap[B]. Ich habe versucht, googeln, aber konnte nicht viel nützliche Ergebnisse für map function for Map in scala :-)

Meine Frage bekommen: Wie in 3 meiner Variation versucht, sich mit map Funktion für diesen Zweck sinnvoll oder sollte ich bleiben bei der Variante 2 die löst tatsächlich mein Problem.

Code:

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 

Antwort

15

In diesem Fall mapValues ​​scheint die geeignetere Methode zu verwenden. Sie würden die map-Methode verwenden, wenn Sie eine Transformation durchführen müssen, die Kenntnisse über die Schlüssel erfordert (z. B. Konvertieren einer Produktreferenz in einen Produktnamen).

Das heißt, die map-Methode ist allgemeiner, da Sie Zugriff sowohl auf die Schlüssel als auch auf die zu bearbeitenden Werte haben. Sie können die mapValues-Methode emulieren, indem Sie die Werte einfach umwandeln und die Schlüssel unverändert lassen das ist, wo Sie in Ihrem Code oben falsch gehen. Um die Karte Methode richtig zu verwenden, sollten Sie eine (Schlüssel, Wert) -Paar von Ihrer Funktion produzieren, nicht nur ein Schlüssel:

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

Wow. Das macht vollkommen Sinn. Vielen Dank, dass Sie sich die Zeit genommen haben, es klar zu erklären. –

+1

Es ist erwähnenswert, dass 'mapValues' eine Sicht auf die vorhandene Map erstellt, während' map' eine komplett neue Map erstellt. – Daenyth

4

Es kann auch sein:

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

Schön. Ich liebe die Art und Weise, wie Scala dir erlaubt, dasselbe in mehr als einer Hinsicht zu tun. Vielen Dank !! –

+0

Dies ist äquivalent zur Verwendung eines Tupels .. d.h. kv ist einfach ein Tupel. – piyushGoyal