2012-03-22 12 views
5

मैं एक परिवर्तनीय Map को एक डिफ़ॉल्ट के साथ बनाने की कोशिश कर रहा हूं जो एक नया ListBuffer बनाता है जब कोई तत्व अनुरोध किया जाता है जो पहले से ही मानचित्र में नहीं है। हालांकि, जबकि नया नक्शा डिफॉल्ट के रूप में लौटाया जाता है, यह मानचित्र में नहीं रहता है। हो सकता है कि यह ठीक है, यह कैसे काम करता है, मैंने सोचा, लेकिन जब मैंने इसे के साथ ListBuffer के बजाय परीक्षण किया, वैसे ही यह वही था जैसा मैं चाहता था। यहां कुछ कोड दिया गया है जो मुझे समझाने के लिए है - मैं क्या गलत कर रहा हूं? एक Map[ListBuffer[Int]] साथस्कैला में एक खाली ListBuffer के साथ मानचित्र

scala> val a = collection.mutable.Map(1 -> 1).withDefault(i => 0) 
a: scala.collection.mutable.Map[Int,Int] = Map(1 -> 1) 

scala> a(1) += 1 // adding to an existing element works as expected 

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

scala> a(2) += 1 // what about adding to a non-existing element? 

scala> a // the new element has been added to the map 
res50: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2, 2 -> 1) 

अब:

सबसे पहले, यहाँ यह एक Map[Int] साथ काम कर रहा है

scala> val b = collection.mutable.Map(1 -> collection.mutable.ListBuffer[Int]()).withDefault(i => collection.mutable.ListBuffer.empty[Int]) 
b: scala.collection.mutable.Map[Int,scala.collection.mutable.ListBuffer[Int]] = Map(1 -> ListBuffer()) 

scala> b(1) += 1 // appending to an existing element works as expected 
res51: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1) 

scala> b 
res52: scala.collection.mutable.Map[Int,scala.collection.mutable.ListBuffer[Int]] = Map(1 -> ListBuffer(1)) 

scala> b(2) += 1 // but appending to a non-existing element... 
res53: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1) 

scala> b // leaves the map unchanged 
res54: scala.collection.mutable.Map[Int,scala.collection.mutable.ListBuffer[Int]] = Map(1 -> ListBuffer(1)) 

उत्तर

3

अंतर यह है:

पहला मामला a(2) में एक Int है । चूंकि Int में += विधि नहीं है, a(2) += 1 बराबर a(2) = a(2) + 1 और a.update(2, a(2) + 1) पर है। update वास्तव में मानचित्र को बदलता है।

लेकिन ListBuffer[Int] एक += विधि है, तो आपके कॉल a(2).+=(1) है, और आप कुछ भी करने के लिए a(2) सेट नहीं है!

+0

ग्रेट, यह समझ में आता है - तो मैं इसे कैसे ठीक कर सकता हूं? क्या मुझे इसे तीन पंक्तियों में करने, तत्व प्राप्त करने, इसे जोड़ने, फिर इसे वापस सेट करने की आवश्यकता है? क्योंकि यदि संभव हो तो मैं इससे बचूंगा! – Russell

+0

मुझे लगता है कि मैं नक्शा कर सकता हूं (i) = नक्शा (i) + = 5 लेकिन यह बहुत क्रोधित दिखता है। – Russell

+1

हां, मुझे ऐसा लगता है (बेशक, आप इसे हमेशा एक अच्छा सहायक विधि में निकाल सकते हैं)। –

1

आप getOrElseUpdate(key: A, op: => B) का उपयोग कर सकते हैं जहां आप सूचीबफर का एक नया उदाहरण बना सकते हैं, जब कुंजी मौजूद नहीं है।

उदा।

val m = collection.mutable.Map[Int, ListBuffer[Int]]() 
m.getOrElseUpdate(1, ListBuffer()) += 1 
+0

+1 क्योंकि यह लिखने के लिए थोड़ा परेशान और लंबी हवादार हो सकता है, * इरादा * बहुत स्पष्ट है। – Russell

संबंधित मुद्दे