2009-09-18 9 views
12

में एक सूची की प्रतिलिपि कैसे करें I Scow में एक सूची कॉपी करना चाहते हैं।स्कैला

val myList = List("foo", "bar") 
val myListCopy = myList.clone 

लेकिन क्लोन विधि सुरक्षित है:

मैं की तरह somehing करना चाहता था।

+0

कि http://stackoverflow.com/questions/1267261/does-scala-anyref-clone-perform-a-shallow-or-deep-copy से संबंधित नहीं किया जा सकते हैं? – VonC

+12

क्या के लिए? सूची वस्तुएं अपरिवर्तनीय हैं। –

+1

मैं सूची से एक तत्व को हटाना चाहता था (एक लूप में निकालें (ए => बूलियन) विधि का उपयोग कर)। (नोट: मैंने 2 घंटे पहले स्कैला शुरू किया :) :) – Maxime

उत्तर

6

एक सूची को फ़िल्टर करने के लिए:

val list = List(1,2,3,4,5) 
//only evens 
val evens = list.filter(e=>e%2 == 0) 

println(list) 
//--> List(1, 2, 3, 4, 5) 

println(evens) 
//--> List(2, 4) 

तुम भी कुछ वर्ण को बचाने के लिए वाइल्डकार्ड का उपयोग कर सकते हैं:

val evens = list.filter(_%2==0) 

ध्यान दें कि, जैसा कि ऊपर टिप्पणी की, सूचियों अपरिवर्तनीय हैं। इसका मतलब है कि ये ऑपरेशन मूल सूची को संशोधित नहीं करते हैं, लेकिन वास्तव में एक नई सूची बनाते हैं।

13

यहां एक गैर-उत्तर है: ऐसा मत करें। एक List अपरिवर्तनीय है, इसलिए एक को कॉपी करने में बिल्कुल कोई बात नहीं है।

के कुछ संचालन पर ध्यान दें:

val list = List(1,2,3) 
val l1 = 0 :: list 
val l2 = "a" :: list 

न तो l1 है और न ही l2list फेरबदल हैं, लेकिन वे दोनों नई सूचियों का संदर्भ list पैदा करते हैं।

आइए इसे विस्तार से समझाएं। कन्स्ट्रक्टर List(1,2,3) तीन तत्व बना रहा है, और एक सिंगलटन ऑब्जेक्ट का भी उपयोग कर रहा है। विशेष रूप से, यह इन तत्वों instantiating है:

::(3, Nil) 
::(2, reference to the previous element) 
::(1, reference to the previous element) 

और Nil एक सिंगलटन वस्तु है। पहचानकर्ता list वास्तव में क्या अंतिम तत्व है इंगित करता है।

::(0, reference to ::(1, etc)) 
बेशक

, list के लिए एक संदर्भ है के बाद से, आप चार तत्वों की सूची के रूप में l1 के बारे में सोच सकते हैं (या:

अब, जब आप 0 :: listl1 को निर्दिष्ट करते हैं, तो आप एक नई वस्तु instantiating कर रहे हैं पांच, यदि आप Nil गिनते हैं)।

अब l2list के समान प्रकार का भी नहीं है, लेकिन यह भी इसका संदर्भ देता है! यहां:

::("a", reference to ::(1, etc)) 

हालांकि, इन सभी वस्तुओं के बारे में महत्वपूर्ण बिंदु यह है कि उन्हें बदला नहीं जा सकता है। कोई सेटर्स नहीं हैं, न ही कोई भी तरीका जो उनकी किसी भी संपत्ति को बदल देगा। वे हमेशा के लिए उनके "सिर" (वही है जिसे हम पहले तत्व कहते हैं) में वही मान/संदर्भ रखते हैं, और उनके "पूंछ" में वही संदर्भ होते हैं (यही वह है जिसे हम दूसरे तत्व कहते हैं)।

हालांकि, देखें जैसे वे सूची बदल रहे हैं। बाकी आश्वासन दिया है कि, वे नई सूचियां बना रहे हैं।उदाहरण के लिए:

val l3 = list map (n => n + 1) 

विधि नक्शा एक पूरी तरह से नई सूची, एक ही आकार के है, जहां नए तत्व list में एक इसी तत्व से गणना की जा सकती है बनाता है (लेकिन आप साथ ही पुराने तत्व की अनदेखी सकता है)।

val l4 = l2 filter (n => n.isInstanceOf[Int]) 

जबकि l4list रूप में एक ही तत्व (लेकिन एक अलग प्रकार) है, यह भी एक पूरी तरह से नए सूची है। विधि filter एक नियम के आधार पर एक नई सूची बनाता है, जिसे आप यह बताते हैं कि कौन से तत्व अंदर जाते हैं और क्या नहीं। यह किसी मौजूदा सूची को वापस करने के मामले में अनुकूलित करने का प्रयास नहीं करता है।

val l5 = list.tail 

यह एक नई सूची नहीं बनाता है। इसके बजाए, यह l5 को list का मौजूदा तत्व असाइन करता है।

val l6 = list drop 2 

फिर से, कोई नई सूची बनाई गई।

val l7 = list take 1 

लेकिन यह एक नई सूची बनाता है, ठीक है क्योंकि यह Nil करने के लिए list के पहले तत्व इसकी पूंछ अंक नहीं बदल सकते हैं ताकि।

यहाँ कुछ अतिरिक्त कार्यान्वयन विवरण है:

  • List एक अमूर्त वर्ग है। इसमें दो वंशज हैं, कक्षा :: (हाँ, यह वर्ग का नाम है), और सिंगलटन ऑब्जेक्ट Nil है। List सील कर दिया गया है, इसलिए आप इसमें नए उप-वर्ग नहीं जोड़ सकते हैं, और :: अंतिम है, इसलिए आप इसे उपclass नहीं कर सकते हैं।

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