2011-09-24 10 views
9

सूची मैप स्टोर का अपरिवर्तनीय संस्करण आरोही क्रम में क्यों है, जबकि उत्परिवर्तनीय संस्करण अवरोही क्रम में संग्रहीत करता है?म्यूटेबल और अपरिवर्तनीय ListMaps के पास स्कैला में अलग-अलग ऑर्डर क्यों हैं?

यहाँ एक परीक्षण है कि आप उपयोग कर सकते हैं अगर आप मिल गया है scalatest-1.6.1.jar और JUnit-4.9.jar

@Test def StackoverflowQuestion() 
    { 
    val map = Map("A" -> 5, "B" -> 12, "C" -> 2, "D" -> 9, "E" -> 18) 
    val sortedIMMUTABLEMap = collection.immutable.ListMap[String, Int](map.toList.sortBy[Int](_._2): _*) 
    println("head : " + sortedIMMUTABLEMap.head._2) 
    println("last : " + sortedIMMUTABLEMap.last._2) 
    sortedIMMUTABLEMap.foreach(X => println(X)) 
    assert(sortedIMMUTABLEMap.head._2 < sortedIMMUTABLEMap.last._2) 

    val sortedMUTABLEMap = collection.mutable.ListMap[String, Int](map.toList.sortBy[Int](_._2): _*) 
    println("head : " + sortedMUTABLEMap.head._2) 
    println("last : " + sortedMUTABLEMap.last._2) 
    sortedMUTABLEMap.foreach(X => println(X)) 
    assert(sortedMUTABLEMap.head._2 > sortedMUTABLEMap.last._2) 
    } 

यहाँ पासिंग परीक्षण के उत्पादन:

head : 2 
last : 18 
(C,2) 
(A,5) 
(D,9) 
(B,12) 
(E,18) 
head : 18 
last : 2 
(E,18) 
(B,12) 
(D,9) 
(A,5) 
(C,2) 
+2

एक अच्छा संग्रह एपीआई का एक प्रमुख लाभ यह है कि यह "विस्तृत रूप से की तरह सभी सनकीपन जानने के लिए होने से बचाता है है इस"। पुनरावृत्ति का क्रम 'सूची मैप' के अनुबंध का हिस्सा नहीं है, इसलिए आपको इसके बारे में कभी सोचना नहीं है। –

+0

एक कम विशिष्ट इंटरफ़ेस विवरण भविष्य में परिवर्तन/सुधार के लिए और अधिक जगह छोड़ देता है। यदि आप तत्व आदेश के संदर्भ में विश्वसनीय व्यवहार चाहते हैं, तो 'सॉर्टेड मैप' का उपयोग करें। – Raphael

+0

धन्यवाद सॉर्ट किया गया मानचित्र मेरे लिए अच्छा काम करता है। – Zasz

उत्तर

12

लक्षणों के सरल किया जा सकता:

scala> collection.mutable.ListMap(1 -> "one", 2 -> "two").foreach(println) 
(2,two) 
(1,one) 

scala> collection.immutable.ListMap(1 -> "one", 2 -> "two").foreach(println) 
(1,one) 
(2,two) 

"छँटाई" अपने कोड में इस मुद्दे के कोर,करने के लिए अपने कॉल नहीं हैListMap.apply सहयोगी ऑब्जेक्ट से कॉल का उपयोग कर रहा है जो एक परिवर्तनीय या अपरिवर्तनीय सूची द्वारा समर्थित एक सूची मानचित्र बनाता है। नियम यह है कि सम्मिलन आदेश संरक्षित किया जाएगा।

अंतर यह प्रतीत होता है कि उत्परिवर्तनीय सूची अपरिवर्तनीय सूची द्वारा समर्थित है और सामने डालें। इसलिए यही कारण है कि आप LIFO व्यवहार प्राप्त करते हैं। मैं अभी भी अपरिवर्तनीय व्यक्ति को देख रहा हूं लेकिन मुझे लगता है कि आवेषण प्रभावी रूप से पीछे हैं। संपादित करें, मैं अपना दिमाग बदल रहा हूं: डालने शायद संभवतः सामने हैं, लेकिन ऐसा लगता है कि immutable.ListMap.iterator विधि लौटाए गए पुनरावर्तक पर toList.reverseIterator के साथ परिणाम को उलट करने का निर्णय लेती है। मुझे लगता है कि इसे मेलिंग सूची में लाने लायक है।

क्या प्रलेखन बेहतर हो सकता है? निश्चित रूप से। क्या दर्द है? वास्तव में नहीं, मैं इसे होने नहीं देता। यदि प्रलेखन अपूर्ण है, तो व्यवहार का परीक्षण करना या किसी अन्य बनाम संरचना चुनने से पहले स्रोत पर देखना बुद्धिमानी है।

असल में, दर्द हो सकता है यदि स्कैला टीम बाद में व्यवहार को बदलने का फैसला करती है और महसूस करती है कि वे व्यवहार प्रभावी ढंग से अनियंत्रित हैं और कोई अनुबंध नहीं है।


आपके उपयोग के मामले के समाधान के लिए टिप्पणी में बताया गया है, कहते हैं कि तुम एक नक्शे में स्ट्रिंग आवृत्ति गिनती एकत्र किया है (परिवर्तनशील या अपरिवर्तनीय):

val map = Map("A" -> 5, "B" -> 12, "C" -> 2, "D" -> 9, "E" -> 18, "B" -> 5) 

के बाद से आप केवल एक बार सॉर्ट करने के लिए की जरूरत है अंत में, आप एक seq और फिर प्रकार के नक्शे से tuples परिवर्तित कर सकते हैं:

map.toSeq.sortBy(_._2) 
// Seq[(java.lang.String, Int)] = ArrayBuffer((C,2), (A,5), (B,5), (D,9), (E,18)) 
+0

अच्छा बिंदु का उपयोग करता हूं, अगर वे अब चीजें बदलते हैं (या बाद में) तो यह एक समस्या होगी। मुझे डीबग करना बहुत मुश्किल लगता है क्योंकि मेरे सॉर्ट टेस्ट और स्रोत में एक ही कोड था, लेकिन ListMap के विभिन्न संस्करण थे। यदि संग्रह में उनके उत्परिवर्तन – Zasz

+0

का प्रतिनिधित्व करने वाले बेहतर नाम होते हैं तो बेहतर होगा यदि मैं सुझाव दे सकता हूं कि आप कौन सी डेटा संरचना का उपयोग करना चाहिए, तो मुझे यह सुझाव सही होगा, मुझे int मान पर क्रमबद्ध (स्ट्रिंग, int) जोड़े की एक क्रमबद्ध तालिका की आवश्यकता है, और सॉर्टिंग के बाद सक्षम। – Zasz

+0

@Zasz, क्या आप अपनी तालिका में एक ही int के लिए डुप्लिकेट या एकाधिक तारों की अनुमति देते हैं? क्या आपको सॉर्ट किए जाने के लिए टेबल की आवश्यकता है क्योंकि इसे उत्परिवर्तित किया गया है? या यह ठीक है अगर आप इसे प्रदर्शित/पुन: प्रदर्शित करने से पहले सॉर्ट करते हैं? जब तक मैं मेलिंग सूची से वापस नहीं सुनता तब तक मैं अपना जवाब स्वीकार नहीं करता ... – huynhjl

4

मैं यह न तो ListMap दावे देखने के रूप में एक क्रमबद्ध नक्शा, सिर्फ एक नक्शा होना करने के लिए एक सूची के साथ लागू किया गया। असल में मैं उनके अनुबंध में कुछ भी नहीं देखता जो सम्मिलन आदेश को संरक्षित करने के बारे में कुछ भी कहता है।

स्कैला में प्रोग्रामिंग बताती है कि शुरुआती तत्वों तक पहुंचने की अधिक संभावना होने पर ListMap का उपयोग किया जा सकता है, लेकिन अन्यथा इसका मानचित्र पर थोड़ा लाभ नहीं होता है।

+1

वास्तव में डेटा संरचनाओं पर पर्याप्त जानकारी के बारे में मेरा क्या मतलब था। स्टार्ट ओवरफ्लो में थ्रेड देखने के बाद सूची मैप का चयन करने के बाद मैं कैसे समाप्त हुआ, जिसने इसे सॉर्ट करने के लिए इस्तेमाल किया। और ListMap दस्तावेज़ के लिए जो लिखा गया है, उसके आधार पर, यह जानना बहुत मुश्किल है कि ListMap का उपयोग कहां करें – Zasz

1

आदेश पर कोई उम्मीद नहीं बनाएं, इसे घोषित नहीं किया गया है और यह स्कैला संस्करणों के बीच अलग-अलग होगा।

उदाहरण के लिए:

import scala.collection.mutable.{ListMap => MutableListMap} 

MutableListMap("A" -> 5, "B" -> 12, "C" -> 2, "D" -> 9, "E" -> 18).foreach(println) 

2,9 पर।1 देता है: (ई, 18) (डी, 9) (सी, 2) (बी, 12) (ए, 5)

लेकिन 2.11.6 पर देता है: (ई, 18) (सी, 2) (ए, 5) (बी, 12) (डी, 9)