स्काला में सूची में आइटम प्राप्त करें?


205

कैसे दुनिया में आप सूचकांक में सिर्फ एक तत्व मिलता है मैं सूची से सूची में?

मैंने कोशिश की get(i), और [i]- कुछ भी काम नहीं करता है। Googling केवल सूची में एक तत्व को "ढूंढना" देता है। लेकिन मुझे पहले से ही तत्व का सूचकांक पता है!

यहाँ वह कोड है जो संकलित नहीं करता है:

def buildTree(data: List[Data2D]):Node ={
  if(data.length == 1){
      var point:Data2D = data[0]  //Nope - does not work

  }
  return null
}

को देखते हुए सूची API , मदद नहीं करता है के रूप में अपनी आँखें बस पार करते हैं।


1
ठीक है, यह डेटा की तरह लगता है। हेड काम किया ... लेकिन फिर भी यह केवल मुझे पहला तत्व देता है, सूची में कोई भी नहीं।
एंड्री Drozdyuk

यदि आप सुनिश्चित करें कि सूचकांक सीमा से बाहर नहीं है, तो Seq traits apply (index) का उपयोग करें । scala-lang.org/api/current/…
बीजर

data.drop (i) .head i-th तत्व तक पहुँचने के लिए काम करता है
विनय

@Vinay यह एक महंगा ऑपरेशन है। तो एक को "ड्रॉप (आई) .हेड" से बचना चाहिए।
शुभम अग्रवाल

जवाबों:


305

कोष्ठक का प्रयोग करें:

data(2)

लेकिन आप वास्तव में बहुत बार सूचियों के साथ ऐसा नहीं करना चाहते हैं, क्योंकि लिंक की गई सूचियों को पार करने में समय लगता है। यदि आप किसी संग्रह में अनुक्रमण करना चाहते हैं, तो Vector(अपरिवर्तनीय) या ArrayBuffer(म्यूटेबल) या संभवतः Array(जो कि सिर्फ एक जावा सरणी है, को छोड़कर फिर से (i)इसके बजाय आप इसमें अनुक्रमित करें [i])।


1
मूल रूप से मैं जावा में ArrayList की तरह कुछ के लिए देख रहा हूँ। मुझे लगता है कि अपरिवर्तनीय भी ठीक होगा।
एंड्री Drozdyuk

1
ArrayBufferजैसे काम करता है ArrayListVectorएक अपरिवर्तनीय की तरह काम करता है - ArrayListआप पढ़ सकते हैं, लेकिन आप एक नया बनाने के बिना नहीं लिख सकते।
रेक्स केर

कैसे एक सबलिस्ट के बारे में? उदाहरण के लिए जावा में मैं "data.subList (0, index)" करता हूं।
एंड्री Drozdyuk

कोई बात नहीं, मुझे मिल गया - यह "टुकड़ा" है! क्या मैं ArrayBuffer को वेक्टर में बदल सकता हूं? या क्या मैं और अधिक सामान्य प्रकार के तरीकों से वापस आ सकता हूं? उदाहरण के लिए जावा में मैं सूची इंटरफ़ेस लौटाऊंगा।
एंड्री Drozdyuk

1
आप ArrayBufferएक IndexedSeqका उपयोग करने के लिए परिवर्तित कर सकते हैं .toIndexedSeq; IndexedSeqअधिक सामान्य प्रकार है। (इस मामले में यह वास्तव में एक के रूप में कार्यान्वित किया जाता है Vector।) IndexedSeqउन संग्रह का सुपरस्क्रिप्ट है जो सूचकांक में उचित हैं। इसके अलावा, ध्यान दें कि आप कर सकते हैं Vector() ++ myArrayBuffer, जो लगभग किसी भी संग्रह (दोनों तरफ) के लिए काम करेगा। ++आपके द्वारा निर्दिष्ट दो में से एक नया संग्रह बनाता है, जो बाईं ओर के प्रकार को संरक्षित करता है। Vector()खाली वेक्टर है, इसलिए यह वही होगा जो आप चाहते हैं।
रेक्स केर

121

सुरक्षित करने के लिए उपयोग करना है, liftतो आप मान निकाल सकते हैं यदि यह मौजूद है और यदि यह नहीं है तो इनायत से विफल रहें।

data.lift(2)

यदि सूची में उस तत्व को प्रदान करने के लिए लंबे समय तक पर्याप्त नहीं है, तो कुछ वापस आ जाएगा और यदि यह है तो कुछ (मान)।

scala> val l = List("a", "b", "c")
scala> l.lift(1)
Some("b")
scala> l.lift(5)
None

जब भी आप एक ऐसा ऑपरेशन कर रहे हैं जो इस तरह से विफल हो सकता है एक विकल्प का उपयोग करना और यह सुनिश्चित करने में मदद करने के लिए टाइप सिस्टम प्राप्त करना कि आप मामले को संभाल रहे हैं जहां तत्व मौजूद नहीं है।

स्पष्टीकरण:

यह काम करता है क्योंकि सूची apply(जो केवल कोष्ठकों को शक्कर देती है, उदाहरण के लिए l(index)) एक आंशिक फ़ंक्शन की तरह है जिसे सूची में कहीं भी परिभाषित किया गया है। List.liftविधि आंशिक बदल जाता है applyसमारोह (एक समारोह है कि केवल कुछ इनपुट के लिए परिभाषित किया गया है) मूल रूप से एक विकल्प में परिणाम लपेटकर द्वारा एक सामान्य समारोह (किसी भी इनपुट के लिए परिभाषित) में।


11
लिफ्ट सुंदर है। मैं arrayIndexOutOfBound त्रुटियों से बच सकते हैं, बिना सरणी के आकार की जाँच के ..
नवीन सच्चर

9

कोष्ठक क्यों?

यहाँ scala में पुस्तक प्रोग्रामिंग से उद्धरण है ।

इस उदाहरण से स्पष्ट एक और महत्वपूर्ण विचार आपको इस बात की जानकारी देगा कि स्केल में कोष्ठक के साथ सरणियों को क्यों एक्सेस किया जाता है। जावा की तुलना में स्काला के पास कम विशेष मामले हैं। सरणी बस किसी भी अन्य वर्ग की तरह स्काला में वर्गों के उदाहरण हैं। जब आप किसी चर पर एक या एक से अधिक मानों के आसपास कोष्ठक लागू करते हैं, तो स्केला कोड को उस चर पर लागू होने वाली विधि के आह्वान में बदल देगा। अतः नमस्कारस्ट्रीम (i) बधाई में बदल जाता है। इस प्रकार स्काला में एक एरे के तत्व को एक्सेस करना किसी भी अन्य की तरह एक तरीका है। यह सिद्धांत सरणियों तक सीमित नहीं है: कोष्ठक में कुछ तर्कों के लिए एक वस्तु के किसी भी आवेदन को एक आवेदन विधि कॉल में बदल दिया जाएगा। बेशक यह केवल तभी संकलित होगा जब उस प्रकार की वस्तु वास्तव में एक लागू पद्धति को परिभाषित करती है। तो यह कोई विशेष मामला नहीं है; यह एक सामान्य नियम है।

कार्यात्मक प्रोग्रामिंग शैली का उपयोग करके कुछ तत्व (इस मामले में पहला एलएम) कैसे खींचना है, इसके कुछ उदाहरण हैं।

  // Create a multdimension Array 
  scala> val a = Array.ofDim[String](2, 3)
  a: Array[Array[String]] = Array(Array(null, null, null), Array(null, null, null))
  scala> a(0) = Array("1","2","3")
  scala> a(1) = Array("4", "5", "6")
  scala> a
  Array[Array[String]] = Array(Array(1, 2, 3), Array(4, 5, 6))

  // 1. paratheses
  scala> a.map(_(0))
  Array[String] = Array(1, 4)
  // 2. apply
  scala> a.map(_.apply(0))
  Array[String] = Array(1, 4)
  // 3. function literal
  scala> a.map(a => a(0))
  Array[String] = Array(1, 4)
  // 4. lift
  scala> a.map(_.lift(0))
  Array[Option[String]] = Array(Some(1), Some(4))
  // 5. head or last 
  scala> a.map(_.head)
  Array[String] = Array(1, 4)


0

यह आजकल सूचकांक के माध्यम से सूची के डेटा तक पहुंचने का पसंदीदा तरीका है:

scala> val list = List("a","b","c")
scala> list.get(1)
Some("b")
scala> list.get(5)
None

लेकिन जैसा कि रेक्स केर उपर्युक्त है: यदि आप अनुक्रमित का उपयोग कर रहे हैं, तो आपको सूची के बजाय वेक्टर का उपयोग करने पर विचार करना चाहिए।

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