2010-12-07 10 views
6

एक अभ्यास के रूप में, मैं अपने स्वयं के OneBasedArray में स्कैला ऐरे संग्रह का विस्तार करना चाहता हूं (जो आप उम्मीद करेंगे, इंडेक्सिंग 1 से शुरू होता है)। चूंकि यह एक अपरिवर्तनीय संग्रह है, मैं इसे सही प्रकार वापसी जब फिल्टर/नक्शा आदिविस्तारित स्कैला संग्रह: एक आधारित ऐरे इंडेक्स व्यायाम

मैं संसाधनों here, here और here पढ़ा है बुला, लेकिन समझने के लिए कि यह कैसे अनुवाद करने के लिए संघर्ष कर रहा हूँ करना चाहते हैं Arrays (या उदाहरणों में से किसी के अलावा संग्रह)। क्या मैं इस तरह की संरचना के साथ सही रास्ते पर हूं?

class OneBasedArray[T] 
    extends Array[T] 
    with GenericTraversableTemplate[T, OneBasedArray] 
    with ArrayLike[T, OneBasedArray] 

क्या कोई और संसाधन है जो संग्रहों को विस्तारित करने में मदद करता है?

उत्तर

2

ऐरे एक विशिष्ट स्कैला संग्रह नहीं है ... यह केवल एक जावा सरणी है जिसे पूर्ण रूपांतरण के माध्यम से संग्रह की तरह दिखने के लिए पिंप किया गया है।

जावा Arrays के गड़बड़-अप भिन्नता को देखते हुए, आप वास्तव में बेहद आकर्षक कारणों के बिना उनका उपयोग नहीं करना चाहते हैं, क्योंकि वे गुप्त बग का स्रोत हैं।

(यहाँ देखें: http://www.infoq.com/presentations/Java-Puzzlers)

एक 1-आधारित संग्रह चरमराती की तरह यह वास्तव में एक अच्छा विचार या तो नहीं है, जैसा कि आप जानने का कोई तरीका नहीं है कि कितने अन्य संग्रहण विधियों धारणा पर भरोसा करते हैं कि अनुक्रम 0-आधारित हैं। तो यह सुरक्षित रूप से करने के लिए (यदि आप वास्तव में होना चाहिए) यदि आप एक नया तरीका है कि डिफ़ॉल्ट एक अपरिवर्तित छोड़ देता जोड़ने चाहता हूँ:

class OneBasedLookup[T](seq:Seq) { 
    def atIdx(i:Int) = seq(i-1) 
} 

implicit def seqHasOneBasedLookup(seq:Seq) = new OneBasedLookup(seq) 

// now use `atIdx` on any sequence. 

भी सुरक्षित अभी भी, आप एक Map[Int,T] बना सकते हैं, सूचकांक होने के साथ एक आधारित

(Iterator.from(1) zip seq).toMap 

यह तर्कसंगत रूप से सबसे "सही" समाधान है, हालांकि इसमें उच्चतम प्रदर्शन लागत भी होगी।

5
  • नए कलेक्शन एपीआई की गहराई में अवलोकन के लिए: The Scala 2.8 Collections API
  • मुख्य वर्गों के बीच संबंध का एक अच्छा दृश्य के लिए और लक्षण this

तरह से मुझे नहीं लगता कि सरणी एक है तक स्कैला में संग्रह।

+0

ब्रावो जानकारी के लिंक जोड़ने के लिए अधिक से अधिक सवाल का जवाब देने ही नहीं, पूछा एक^_^ –

+1

@Dylan बस जवाब "वहाँ किसी भी आगे संसाधन है कि मदद का विस्तार संग्रह समझाने हैं?" :) – pedrofurla

3

यहाँ एक विधि है जो हमेशा iterable की उम्मीद क्रम प्रकार देता है उस पर चल रही है साथ iterables रोगी का एक उदाहरण है:

import scala.collection.generic.CanBuildFrom 

trait MapOrElse[A] { 
    val underlying: Iterable[A] 

    def mapOrElse[B, To] 
     (m: A => Unit) 
     (pf: PartialFunction[A,B]) 
     (implicit cbf: CanBuildFrom[Iterable[A], B, To]) 
     : To = { 

    var builder = cbf(underlying.repr)   

    for (a <- underlying) if (pf.isDefinedAt(a)) builder += pf(a) else m(a) 

    builder.result 
    } 
} 

implicit def toMapOrElse[A](it: Iterable[A]): MapOrElse[A] = 
    new MapOrElse[A] {val underlying = it} 

नए कार्य mapOrElsecollect समारोह के समान है, लेकिन यह करने की अनुमति देता एक आंशिक फ़ंक्शन pf के अलावा को अपरिभाषित होने पर भी एक विधि m: A => Unit पास करें। m उदाहरण के लिए लॉगिंग विधि हो सकता है।

3

एक ArrayTraversable नहीं है - बेस क्लास के रूप में काम करने की कोशिश कर रहे सभी प्रकार की समस्याएं पैदा होंगी। इसके अलावा, यह अपरिवर्तनीय नहीं है, जो इसे आप जो चाहते हैं उसे पूरी तरह से अनुपयुक्त बनाता है। अंत में, Array एक कार्यान्वयन है - लक्षणों या सार वर्गों से प्राप्त करने का प्रयास करें।

0

कोई सरणी नहीं है, लेकिन यहां एक एक-आधारित अपरिवर्तनीय इंडेक्सडैक कार्यान्वयन है जिसे मैंने हाल ही में एक साथ रखा है। मैंने here दिए गए उदाहरण का पालन किया जहां वे एक आरएनए कक्षा लागू करते हैं। उस उदाहरण के बीच, ScalaDocs, और "सहायक" कंपाइलर त्रुटियों के बहुत सारे, मैं इसे सही तरीके से स्थापित करने में कामयाब रहा। तथ्य यह है कि OneBasedSeq जेनेरिक है, इसे आरएनए उदाहरण से थोड़ा अधिक जटिल बना दिया गया है। इसके अलावा, उदाहरणों में विस्तारित तरीकों और विधियों को ओवरराइड करने के अलावा, मुझे IterableLike का विस्तार करना था और iterator विधि को ओवरराइड करना था, क्योंकि विभिन्न विधियां दृश्यों के पीछे उस विधि को कॉल करती हैं, और डिफ़ॉल्ट इटरेटर शून्य-आधारित है।

कृपया किसी भी स्टाइलिस्ट या मुहावरे संबंधी विषमता को क्षमा करें; मैं 2 महीने से भी कम समय के लिए स्कैला में प्रोग्रामिंग कर रहा हूं।

import collection.{IndexedSeqLike, IterableLike} 
import collection.generic.CanBuildFrom 
import collection.mutable.{Builder, ArrayBuffer} 

// OneBasedSeq class 
final class OneBasedSeq[T] private (s: Seq[T]) extends IndexedSeq[T] 
    with IterableLike[T, OneBasedSeq[T]] with IndexedSeqLike[T, OneBasedSeq[T]] 
{ 
    private val innerSeq = s.toIndexedSeq 

    def apply(idx: Int): T = innerSeq(idx - 1) 
    def length: Int = innerSeq.length 
    override def iterator: Iterator[T] = new OneBasedSeqIterator(this) 
    override def newBuilder: Builder[T, OneBasedSeq[T]] = OneBasedSeq.newBuilder 
    override def toString = "OneBasedSeq" + super.toString 
} 

// OneBasedSeq companion object 
object OneBasedSeq { 
    private def fromSeq[T](s: Seq[T]) = new OneBasedSeq(s) 

    def apply[T](vals: T*) = fromSeq(IndexedSeq(vals: _*)) 

    def newBuilder[T]: Builder[T, OneBasedSeq[T]] = 
    new ArrayBuffer[T].mapResult(OneBasedSeq.fromSeq) 

    implicit def canBuildFrom[T, U]: CanBuildFrom[OneBasedSeq[T], U, OneBasedSeq[U]] = 
    new CanBuildFrom[OneBasedSeq[T], U, OneBasedSeq[U]] { 
     def apply() = newBuilder 
     def apply(from: OneBasedSeq[T]): Builder[U, OneBasedSeq[U]] = newBuilder[U] 
    } 
} 

// Iterator class for OneBasedSeq 
class OneBasedSeqIterator[T](private val obs: OneBasedSeq[T]) extends Iterator[T] 
{ 
    private var index = 1 
    def hasNext: Boolean = index <= obs.length 

    def next: T = { 
    val ret = obs(index) 
    index += 1 
    ret 
    } 
} 
संबंधित मुद्दे