2012-07-31 11 views
24

जब दो अपरिवर्तनीय नक्शे श्रृंखलाबद्ध, ऐसा लगता है कि सही संकार्य के तत्वों "के ऊपर लिख" होगा छोड़ दिया है एक के तत्वों:दो अपरिवर्तनीय मानचित्रों को जोड़ें - कौन से तत्वों को प्राथमिकता दी जाती है?

scala> List((1, 2), (5, 6)).toMap ++ List((5, 9)).toMap 
res13: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 5 -> 9) 

scala> List((5, 9)).toMap ++ List((1, 2), (5, 6)).toMap 
res14: scala.collection.immutable.Map[Int,Int] = Map(5 -> 6, 1 -> 2) 

मुझे पता करना चाहते हैं, अगर यह स्काला में एक नियम है?

स्कैला एपीआई से मैं इस सवाल को नहीं समझ पाया।

उत्तर

20

हाँ, इस व्यवहार निरंतर

+2

धन्यवाद। यदि आप मुझे यह भी बता सकते हैं कि (या संदर्भ जहां नियम परिभाषित किया गया है) दें, तो आपको स्वीकार्य उत्तर प्राप्त होगा। :-) –

+2

ज्यादातर मामलों में '++' का कार्यान्वयन '+' पर निर्भर करता है, जो इसके बदले में 'अद्यतन' पर निर्भर करता है और [इस] (http://www.scala-lang.org/api/current /scala/collection/immutable/Map.html) स्केलैडोक यह कहा गया है कि 'अपडेट किया गया' नए मानों के साथ अपडेट किया गया एक नया अपरिवर्तनीय मानचित्र देता है। हाँ, मुझे पता है, एक पूर्ण प्रमाण नहीं, तो शायद आपको अभी तक इस प्रश्न को बंद नहीं करना चाहिए और बेहतर संदर्भ की प्रतीक्षा करनी चाहिए। हालांकि "जावा मैप" संदर्भ बैल $ हिट है। –

11

Map.++is defined as है:

override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): immutable.Map[A, B1] = 
    ((repr: immutable.Map[A, B1]) /: xs.seq) (_ + _) 

जहां repr अपने वर्तमान नक्शा और xs.seq आप नक्शे आप ++ के पास में संग्रहीत जोड़े/मैपिंग का एक दृश्य देता है।


Map./:is described as:

def /:[B](z: B)(op: (B, (A, B)) ⇒ B): B 

Applies a binary operator to a start value and all elements of this 
immutable map, going left to right. 

Note: /: is alternate syntax for foldLeft; 
z /: xs is the same as xs foldLeft z. 

नोट यह निर्दिष्ट नहीं है कि क्या "बाएं से दाएं" एक अव्यवस्थित नक्शे के लिए मायने रखता है।


निम्नलिखित दिखाता है क्या ++ reimplementing और println बयान डिबग के साथ इसे बढ़ाने से दृश्य के पीछे क्या होता:

val m1 = Map(1 -> "A", 2 -> "B", 3 -> "C") 
val m2 = Map(2 -> "X", 3 -> "Y", 4 -> "Z") 

println(m1.repr) 
    /* Map(1 -> A, 2 -> B, 3 -> C) */ 
println(m1.repr.getClass.getName) 
    /* scala.collection.immutable.Map$Map3 */ 

def ++[K, V](ts: Map[K, V], xs: Map[K, V]): Map[K, V] = 
    (ts /: xs) {case (acc, entry) => 
       println("acc = " + acc) 
       println("entry = " + entry) 
       acc + entry 
       } 

val m3 = ++(m1, m2) 
    /* 
    acc = Map(1 -> A, 2 -> B, 3 -> C) 
    entry = (2,X) 
    acc = Map(1 -> A, 2 -> X, 3 -> C) 
    entry = (3,Y) 
    acc = Map(1 -> A, 2 -> X, 3 -> Y) 
    entry = (4,Z) 
    */ 

println(m3) 
    /* Map(1 -> A, 2 -> X, 3 -> Y, 4 -> Z) */ 
+0

आपकी विधि ++ में, आपको xs.seq नहीं मिल रहा है जैसा कि आपने पहले बताया था। ऐसा क्यों है? – Felix

+0

@ फ़ेलिक्स 'अपरिवर्तनीय। मैप 'खुद को वापस करने के लिए' def seq' ओवरराइड करता है, यानी,' यह ', 'xs.seq' इसलिए उसी मानचित्र पर' xs' करता है। मुझे लगता है कि कोई उप-वर्गों में 'def seq' को ओवरराइड कर सकता है, लेकिन मुझे यह देखने के लिए संग्रह पुस्तकालय के आंतरिक डिज़ाइन के बारे में पर्याप्त जानकारी नहीं है कि यह कब उपयोगी या आवश्यक होगा। –