रिक्त सूची कैसे घोषित करें और फिर स्केला में स्ट्रिंग जोड़ें?


81

मेरे पास इस तरह का कोड है:

val dm  = List[String]()
val dk = List[Map[String,Object]]()

.....

dm.add("text")
dk.add(Map("1" -> "ok"))

लेकिन यह रनटाइम java.lang.UnsupportedOperationException को फेंकता है।

मुझे खाली सूची या खाली नक्शे घोषित करने की आवश्यकता है और कुछ कोड में बाद में उन्हें भरने की आवश्यकता है।


आपको क्या लगता है कि कोई addऑपरेशन है List?
डेबिल्स्की

यदि आप ऐड ऑपरेशन का उपयोग करना चाहते हैं, तो आपको एक ArrayList घोषित करना होगा। स्कैला में दालें अनिवार्य रूप से अपरिवर्तनीय होती हैं, इसलिए आप उन्हें नहीं जोड़ सकते।
फैंटम P३

1
iirc वैल अंतिम की तरह अधिक है, यदि आप परस्पर संग्रह का उपयोग करते हैं तो आप उन्हें जोड़ सकते हैं। उदा। scala-lang.org/api/current/scala/collection/mutable/…
Davinci

1
@rjc आप किस स्केला का उपयोग कर रहे हैं? मेरा (2.9.0) मुझे एक संकलन त्रुटि देता है।
प्रतिमान

4
क्या आपने आयात किया scala.collection.JavaConversions? यदि आपने किया है, तो आप बहुत ही कारण देख रहे हैं कि मैं JavaConvertersइसके बजाय सिफारिश क्यों करता हूं : dmऔर dkजावा संग्रह में परिवर्तित किया जा रहा है, और फिर addउस संग्रह पर कॉल की गई विधि। इससे भी बदतर, dmऔर dkसंशोधित नहीं किया जा रहा है, भले ही आपको कोई त्रुटि न मिली हो। और, वैसे, त्रुटि है कि है 1 -> "ok"है Map[Int,String], नहीं Map[String, Object]
डेनियल सी। सोबरल

जवाबों:


117

स्केल सूचियां डिफ़ॉल्ट रूप से अपरिवर्तनीय हैं। आप एक तत्व को "जोड़" नहीं सकते, लेकिन आप नए तत्व को सामने रखकर एक नई सूची बना सकते हैं। चूंकि यह एक नई सूची है, इसलिए आपको संदर्भ को फिर से असाइन करने की आवश्यकता है (ताकि आप एक घाटी का उपयोग न कर सकें)।

var dm  = List[String]()
var dk = List[Map[String,AnyRef]]()

.....

dm = "text" :: dm
dk = Map(1 -> "ok") :: dk

ऑपरेटर ::नई सूची बनाता है। तुम भी छोटे वाक्यविन्यास का उपयोग कर सकते हैं:

dm ::= "text" 
dk ::= Map(1 -> "ok")

एनबी: में प्रकार का उपयोग स्काला नहीं Objectलेकिन Any, AnyRefया AnyVal


बहुत अच्छा उत्तर लेकिन क्या आप बता सकते हैं कि अगर मैं आपके उत्तर की तरह सूची की घोषणा करता हूं, तो क्या वे scala.collections.mutable या अपरिवर्तनीय प्रकार के हैं? आरईपीएल ने यह स्पष्ट नहीं किया।
rjc

2
डिफ़ॉल्ट रूप से। यदि आप कुछ भी आयात नहीं करते हैं। Listअपरिवर्तनीय है। यह सबसे अधिक उपयोग के लिए एक की सिफारिश की है।
पैराडाइमैटिक

11
@ आरजेसी स्काला में ए mutable.List- Listएक ठोस प्रकार नहीं है, जिसमें से केवल कार्यान्वयन अपरिवर्तनीय है। वहाँ इस तरह के रूप अपरिवर्तनीय वर्ग हैं LinkedListऔर DoubleLinkedList, जो ज्यादातर सहायक वर्ग हैं। जावा के के स्काला बराबर ArrayListहै ArrayBuffer, और जावा के के बराबर LinkedListहै ListBuffer। वह विशेषता जो जावा के अनुरूप Listहै Seq- जिसमें से एक है collection.Seqऔर, इसका विस्तार, collection.immutable.Seqऔर collection.mutable.Seq
डेनियल सी। सोबरल

@paradigmatic के बीच अंतर है ::=और +=?
महदी

@ मेहदी में अंतर हो सकता है। केवल सूची ::में परिभाषित किया गया है इसलिए +=काम नहीं करेगा। अन्य संग्रह पर (मानक लिब में नहीं): यदि लागू किया जाता है ::=या +=लागू किया जाता है, तो उपयोग किया जाएगा। वरना, संकलक बदल जाएगी x::=yमें x = y::xऔर x+=yinro x=x+y। दूसरे मामले में, वे एक ही के कार्यान्वयन अगर कर रहे हैं ::के कार्यान्वयन के रूप में ही है +...
निदर्शनात्मक

17

यदि आपको सामान को म्यूट करने की आवश्यकता है, तो इसका उपयोग करें ArrayBufferया LinkedBufferइसके बजाय। हालाँकि, इस कथन को संबोधित करना बेहतर होगा:

मुझे खाली सूची या खाली नक्शे घोषित करने की आवश्यकता है और कुछ कोड में बाद में उन्हें भरने की आवश्यकता है।

ऐसा करने के बजाय, तत्वों को वापस करने वाले कोड के साथ सूची भरें। ऐसा करने के कई तरीके हैं, और मैं कुछ उदाहरण दूंगा:

// Fill a list with the results of calls to a method
val l = List.fill(50)(scala.util.Random.nextInt)

// Fill a list with the results of calls to a method until you get something different
val l = Stream.continually(scala.util.Random.nextInt).takeWhile(x => x > 0).toList

// Fill a list based on its index
val l = List.tabulate(5)(x => x * 2)

// Fill a list of 10 elements based on computations made on the previous element
val l = List.iterate(1, 10)(x => x * 2)

// Fill a list based on computations made on previous element, until you get something
val l = Stream.iterate(0)(x => x * 2 + 1).takeWhile(x => x < 1000).toList

// Fill list based on input from a file
val l = (for (line <- scala.io.Source.fromFile("filename.txt").getLines) yield line.length).toList

14

जैसा कि सभी ने पहले ही उल्लेख किया है, यह स्काला में सूचियों का उपयोग करने का सबसे अच्छा तरीका नहीं है ...

scala> val list = scala.collection.mutable.MutableList[String]()
list: scala.collection.mutable.MutableList[String] = MutableList()

scala> list += "hello"
res0: list.type = MutableList(hello)

scala> list += "world"
res1: list.type = MutableList(hello, world)

scala> list mkString " "
res2: String = hello world

क्या आप बता सकते हैं कि यदि आपकी सूची आपके उत्तर की तरह घोषित की जाती है, तो क्या यह पैराडाइमेटिक द्वारा उत्तर देने के विपरीत बेहतर रनटाइम प्रदर्शन देगा? मान लें कि लाखों तत्व सूची में जोड़ दिए जाएंगे।
rjc

यह इस बात पर निर्भर करता है कि आप क्या हासिल करने की कोशिश कर रहे हैं। मैं एक अपरिवर्तनीय के साथ शुरू करने की सलाह दूंगा जैसा कि @paradigmatic ने सुझाव दिया है। एक तत्व को इस तरह एक अपरिवर्तनीय सूची में जोड़ने की जटिलता: list ::= "text"ओ (1) है जो निरंतर है और सबसे अच्छा आप कर सकते हैं।
Agilesteel

rjc: अपरिवर्तनीय सूचियों का विपक्ष O (1) है; हालाँकि, वास्तव में जो मायने रखता है वह है आपका एक्सेस पैटर्न जहाँ तक दक्षता की बात है। उदाहरण के लिए, यदि ऑर्डर मायने रखता है और आपको सूची को जोड़कर बनाना चाहिए, तो वेक्टर एक बेहतर (अपरिवर्तनीय) विकल्प है।
क्राइस न्यूटीकॉम्बे

6

जैसा कि ऊपर दिए गए उत्तर में कहा गया है , स्काला सूची एक अपरिवर्तनीय संग्रह है। आप के साथ एक खाली सूची बना सकते हैं .empty[A]। तो फिर तुम एक विधि का उपयोग कर सकते हैं :+, +:या ::सूची तत्व जोड़ने के लिए।

scala> val strList = List.empty[String]
strList: List[String] = List()

scala> strList:+ "Text"
res3: List[String] = List(Text)

scala> val mapList = List.empty[Map[String, Any]]
mapList: List[Map[String,Any]] = List()

scala> mapList :+ Map("1" -> "ok")
res4: List[Map[String,Any]] = List(Map(1 -> ok))

2

स्कैला में प्रति डिफ़ॉल्ट संग्रह अपरिवर्तनीय है, इसलिए आपके पास एक + तरीका है जो इसमें जोड़े गए तत्व के साथ एक नई सूची देता है। अगर आपको वास्तव में एक ऐड मेथड की तरह कुछ चाहिए तो आपको एक म्यूटेबल कलेक्शन चाहिए, जैसे http://www.scala-lang.org/api/current/scala/collection/mutable/MutableList.html जिसमें + = मेथड है।


0

हो सकता है कि आप खाली सूची बनाने और बाद में तार जोड़ने के लिए लिस्ट में बफ़र का उपयोग कर सकते हैं क्योंकि लिस्ट बफ़र परस्पर हैं। इसके अलावा सभी सूची कार्यों के लिए सूची में उपलब्ध हैं scala।

import scala.collection.mutable.ListBuffer 

val dm = ListBuffer[String]()
dm: scala.collection.mutable.ListBuffer[String] = ListBuffer()
dm += "text1"
dm += "text2"
dm = ListBuffer(text1, text2)

यदि आप चाहते हैं कि आप .toList का उपयोग करके इसे सूची में बदल सकते हैं


0

आपके मामले में मैं उपयोग करता हूं: val dm = ListBuffer[String]()औरval dk = ListBuffer[Map[String,anyRef]]()

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.