2017-10-13 21 views
4

Je suis nouveau sur scala. L'exemple suivant, je suis un peu confus de ce qui se passe. J'ai créé une carte mutable, puis j'ai poussé trois clés/valeur sur la carte. Je peux récupérer la file d'attente avec des valeurs par clé, mais "web.keys" montre que la carte est vide, et "web.size" renvoie 0! Pourquoi est-ce, et comment puis-je récupérer la bonne taille de la carte?scala - pourquoi map.size renvoie 0 lorsque la carte n'est pas vide

scala> import scala.collection.mutable.{Map, Set, Queue, ArrayBuffer} 

scala> val web = Map[Int, Queue[Long]]().withDefaultValue(Queue()) 
web: scala.collection.mutable.Map[Int,scala.collection.mutable.Queue[Long]] = Map() 

scala> web(123).enqueue(567L) 

scala> web(123).enqueue(1L) 

scala> web(123).enqueue(2L) 

scala> web(123) 
res96: scala.collection.mutable.Queue[Long] = Queue(567, 1, 2) 

scala> web 
res97: scala.collection.mutable.Map[Int,scala.collection.mutable.Queue[Long]] = Map() 

scala> web.size 
res98: Int = 0 

scala> web.keys 
res99: Iterable[Int] = Set() 

Une carte simple fonctionne correctement.

scala> val w= Map[Int,Int]() 
w: scala.collection.mutable.Map[Int,Int] = Map() 

scala> w(1)=1 

scala> w 
res10: scala.collection.mutable.Map[Int,Int] = Map(1 -> 1) 

scala> w(2)=2 

scala> w 
res12: scala.collection.mutable.Map[Int,Int] = Map(2 -> 2, 1 -> 1) 

scala> w.size 
res13: Int = 2 

J'ai essayé plus d'expérience, il semble que cela ait quelque chose à voir avec "withDefaultValue". Mais comment puis-je le réparer?

scala> val ww= Map[Int,Int]().withDefaultValue(0) 
ww: scala.collection.mutable.Map[Int,Int] = Map() 

scala> ww 
res14: scala.collection.mutable.Map[Int,Int] = Map() 

scala> ww(1) += 1 

scala> ww(2) += 2 

scala> w.size 
res17: Int = 0 
+0

Copie possible de [Pourquoi ma carte ne prétend-elle pas avoir de clés après l'ajout de clés?] (Https://stackoverflow.com/questions/44532916/why-does-my-map-claim-to-ha-no- keys-after-adding-keys) ou [Comportement de withDefaultValue dans mutable.Map] (https://stackoverflow.com/q/46650121/1048572) – Bergi

Répondre

5

Lorsque la valeur par défaut est renvoyée de la carte, elle n'est pas ajoutée à la carte! Ainsi, lors de l'appel web(123)

rien n'est ajouté à la carte, seule la valeur par défaut est renvoyée. Utilisez la méthode getOrElseUpdate pour lire les données au lieu de d'utiliser la carte avec la valeur par défaut. Ou prenez simplement en compte que la valeur par défaut n'est pas dans la carte comme les autres paires clé-valeur.

Je pense que vous comprenez mal vos exemples sont:

Dans premier exemple web(123).enqueue(567L) vous retrieveing ​​valeur par défaut et en ajoutant 567L la valeur par défaut (file d'attente). Rien n'est ajouté à la carte.

Dans la deuxième exemple w(1)=1 vous ajoutez des données pour cartographier

Dans troisième exemple ww(1) += 1 vous récupérez la valeur par défaut (0) et en ajoutant 1 à elle.

En général utilisant map(K) retournera la valeur pour clé K, tandis que map(K) = V sera mis en valeur V pour la clé K.

Sous le capot invoquant map(K) et map(K) = V utilisations et appliquent des méthodes de mise à jour. Voir http://otfried.org/scala/apply.html ou autre documentation de scala pour plus de détails.

+0

Merci! Je vois. Je pensais que cela fonctionnerait comme python defaultdict. – user1269298

+1

juste pour souligner (c'est ce qui m'a troublé quand j'ai vu ça). Si vous voulez faire web (124), vous obtiendrez toujours la valeur par défaut mise en file d'attente. La valeur par défaut est une file d'attente modifiable que vous modifiez. –