2015-04-07 3 views
2

Scala immutable Map a un membre mapValues, qui permet d'effectuer le mappage sur des valeurs uniquement (pas les clés). Lorsque vous utilisez immutable ListMap à la place, ce membre est hérité, mais il n'est pas remplacé, donc il renvoie toujours un Map, pas ListMap.Remplacer mapValues ​​pour ListMap

Existe-t-il un moyen simple de mettre en œuvre mapValues pour un ListMap?

Dans le fragment suivant, je veux que le type de retour d'être un ListMap, non Map:

import scala.collection.immutable.ListMap 

val lm = ListMap(1 -> "1", 0 -> "0", 2 -> "2") 

lm.mapValues (v => v+v) 
+1

Juste Pour votre information, cela arrive parce que 'mapValues', contrairement' map' et d'autres combinateurs génériques, retourne une vue * * à la carte existante et non à une nouvelle collection. Vous devez matérialiser cette vue, mais il semble n'y avoir aucun moyen plus facile que de réimplémenter 'mapValues' via' map' ou d'ajouter des valeurs à une nouvelle carte. –

Répondre

2

Que diriez-vous:

def listMapValues[K,V1,V2](lm:ListMap[K,V1], f: V1 => V2) = lm.map { case (k,v1) => (k,f(v1))} 

Vous pouvez alors l'utiliser comme:

scala> listMapValues(lm, v => v + v) 
res16: scala.collection.immutable.ListMap[Int,String] = Map(1 -> 11, 0 -> 00, 2 -> 22) 

Si vous voulez l'utiliser comme méthode infixe, il suffit de le déclarer implicite t class:

implicit class ListMapOps[K,V1](lm: ListMap[K,V1]) { 
    def listMapValues[V2](f: V1 => V2)= lm.map { case (k,v1) => (k,f(v1))} 
    } 


scala> lm.listMapValues(v => v + v) 
res17: scala.collection.immutable.ListMap[Int,String] = Map(1 -> 11, 0 -> 00, 2 -> 22) 
+3

'lm.transform ((_, v) => v + v)' fonctionne également très bien. –

2

Vous pouvez faire ceci.

ListMap[Int, String]().empty ++ lm.mapValues(v => v + v) 

Votre code:

import scala.collection.immutable.ListMap 
    val lm: ListMap[Int, String] = ListMap(1 -> "1", 0 -> "0", 2 -> "2") 
    val result: ListMap[Int, String] = ListMap[Int, String]().empty ++ lm.mapValues(v => v + v) 

Sortie à REPL:

import scala.collection.immutable.ListMap 
lm: scala.collection.immutable.ListMap[Int,String] = Map(1 -> 1, 0 -> 0, 2 -> 2) 
result: scala.collection.immutable.ListMap[Int,String] = Map(1 -> 11, 0 -> 00, 2 -> 22) 
+0

Y at-il une garantie 'lm.mapValues' et' ++ 'avec' Map' maintiendra l'ordre? D'où vient la garantie? – Suma

+0

oui, car il ne fait qu'ajouter la carte calculée à une ListMap vide. – curious

+0

@curious, mais le 'Map' calculé peut avoir déjà perdu l'ordre, puisque ce n'est pas un' ListMap' – Chirlo