2010-08-14 18 views
8

ListSet (collection.immutable.ListSet) एक व्यस्त क्रमबद्ध सेट है। मुझे आदेश सेट की जरूरत है। यह मूल ListSet का एक उदाहरण है:सम्मिलन-आदेश दिया गया सूचीसेट

var a = ListSet(1,2,3) 
var ite = a.iterator 
ite.next // returns 3 
ite.next // returns 2 
ite.next // returns 1 

और यह एक उदाहरण की आवश्यकता है:

var a = ListSet(1,2,3) 
var ite = a.iterator 
ite.next // returns 1 
ite.next // returns 2 
ite.next // returns 3 

अद्यतन:

"आदेश दिया" एक "निवेशन आदेश दिया," मेरे लिए। मुझे इसकी आवश्यकता है:

var a = ListSet(1,2,3) 
a += 5 
a += 4 
var ite = a.iterator 
ite.next // returns 1 
ite.next // returns 2 
ite.next // returns 3 
ite.next // returns 5 
ite.next // returns 4 

उत्तर

1
import collection.SetLike 
import collection.generic.{CanBuildFrom, ImmutableSetFactory, GenericCompanion, GenericSetTemplate} 

@serializable @SerialVersionUID(2L) 
class OrderedListSet[A] extends Set[A] 
        with GenericSetTemplate[A, OrderedListSet] 
        with SetLike[A, OrderedListSet[A]] { 

    override def companion: GenericCompanion[OrderedListSet] = OrderedListSet 

    override def size: Int = 0 

    override def empty = OrderedListSet.empty[A] 

    def iterator: Iterator[A] = Iterator.empty 

    override def foreach[U](f: A => U): Unit = { } 

    def contains(e: A): Boolean = get0(e) 

    override def + (e: A): OrderedListSet[A] = updated0(e) 

    override def + (elem1: A, elem2: A, elems: A*): OrderedListSet[A] = this + elem1 + elem2 ++ elems 

    def - (e: A): OrderedListSet[A] = removed0(e) 

    protected def get0(key: A): Boolean = false 

    protected def updated0(key: A): OrderedListSet[A] = 
    new OrderedListSet.OrderedListSet1(key) 

    protected def removed0(key: A): OrderedListSet[A] = this 

    protected val indexes:List[Int] = List[Int]() 

    protected val nextIndex:Int = 1 

    def pairIterator:Iterator[(A,Int)] = Iterator.empty 

    protected def writeReplace(): AnyRef = new OrderedListSet.SerializationProxy(this) 

    protected def pairForeach[U](f: ((A,Int)) => U): Unit = { } 
} 


object OrderedListSet extends ImmutableSetFactory[OrderedListSet] { 
    /** $setCanBuildFromInfo */ 
    implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, OrderedListSet[A]] = setCanBuildFrom[A] 
    override def empty[A]: OrderedListSet[A] = EmptyOrderedListSet.asInstanceOf[OrderedListSet[A]] 

    private object EmptyOrderedListSet extends OrderedListSet[Any] { 
    } 

    class OrderedListSet1[A](private[OrderedListSet] var key: A) extends OrderedListSet[A] { 

    override def size = 1 

    override val indexes = List[Int](1) 

    override val nextIndex = indexes.head + 1 

    override def get0(key: A): Boolean = (key == this.key) 

    override def updated0(key: A): OrderedListSet[A] = 
     if (this.key == key) { 
     this 
     } else { 
     val m = new EEOrderedListSet[A](List[A](this.key), indexes, nextIndex) 
     m.updated0(key) 
     } 

    override def removed0(key: A): OrderedListSet[A] = if (key == this.key) OrderedListSet.empty[A] else this 

    override def iterator = Iterator(key) 

    override def pairIterator: Iterator[(A, Int)] = Iterator((key, indexes.head)) 

    override def foreach[U](f: A => U): Unit = f(key) 

    override def pairForeach[U](f: ((A,Int)) => U): Unit = f (key, indexes.head) 
    } 


    class EEOrderedListSet[A](private var elems: List[A], 
           override protected[OrderedListSet] val indexes: List[Int], 
           override protected[OrderedListSet] val nextIndex:Int) 
      extends OrderedListSet[A] { 

    override def size = elems.size 

    override def get0(key: A): Boolean = elems.contains(key) 

    override def updated0(key: A): OrderedListSet[A] = { 
     if (elems contains key) { 
     this 
     } else { 
     new EEOrderedListSet(elems.:+(key), indexes.:+(nextIndex), nextIndex+1) 
     } 
    } 

    override def removed0(key: A): OrderedListSet[A] = { 
     val r = elems findIndexOf (_ == key) 
     if (r != -1) { 
     val e = elems filterNot (_ == key) 
     val (i1, i2) = indexes splitAt r 
     val i = i1 ++ i2.tail 
     new EEOrderedListSet(e, i, nextIndex) 
     } else { 
     this 
     } 
    } 

    override def iterator = elems.iterator 

    override def pairIterator: Iterator[(A, Int)] = (elems zip indexes).iterator 

    override def foreach[U](f: A => U): Unit = elems.foreach(f) 

    override def pairForeach[U](f: ((A,Int)) => U): Unit = (elems zip indexes).foreach(f) 
    } 

    @serializable @SerialVersionUID(2L) private class SerializationProxy[A,B](@transient private var orig: OrderedListSet[A]) { 
    private def writeObject(out: java.io.ObjectOutputStream) { 
     val s = orig.size 
     out.writeInt(s) 
     for (e <- orig) { 
     out.writeObject(e) 
     } 
    } 

    private def readObject(in: java.io.ObjectInputStream) { 
     orig = empty 
     val s = in.readInt() 
     for (i <- 0 until s) { 
     val e = in.readObject().asInstanceOf[A] 
     orig = orig + e 
     } 
    } 

    private def readResolve(): AnyRef = orig 
    } 

} 
1

वास्तव में, यह एक आदेशित सेट नहीं है। यदि आपको आदेश की आवश्यकता है, तो immutable.SortedSet, जैसे कि immutable.TreeSet के कार्यान्वयन का उपयोग करें।

+0

ओपी स्पष्ट किया कि उनका मतलब "प्रविष्टि-आदेश दिया गया" के बजाय "का आदेश दिया"। –

+0

@anov, मैं इसे देखता हूं। हालांकि, मुझे प्रश्न के नए संस्करण का समाधान नहीं पता है। –

4

यह आदेश दिया है:

val a = ListSet(3,1,2) 
val ite = a.iterator 
ite.next // returns 2 
ite.next // returns 1 
ite.next // returns 3 
+0

हाँ !, इनका आदेश नहीं दिया गया है। क्यूं कर? – barroco

+0

@ isola009 ए 'सेट' का आदेश नहीं दिया गया है। एक 'सूचीसेट' एक 'सूची' द्वारा समर्थित 'सेट' है, और 'सूची' में सामान जोड़ने का सबसे अच्छा तरीका तत्वों को प्रीपेड करना है। इसलिए, 'सेट' का समर्थन करने वाली' सूची 'में जोड़ा गया अंतिम तत्व उस' सूची' का पहला तत्व होगा, जो आपके द्वारा 'इटेटर' का उपयोग करते समय दिखाई देने वाले व्यवहार का कारण बनता है। –

12

collection.mutable.LinkedHashSet एक सेट है कि उसी क्रम वे डाला गया में अपने सदस्यों iterates है। (मैं से बचने के लिए शब्द "का आदेश दिया" यहाँ, के बाद से मैं मूल्यों पर एक आदेश संबंध के मामलों के लिए है कि आरक्षित करना पसंद करते हैं, न कि विशिष्ट अनुक्रम जिसमें कुछ कार्रवाई किए गए।)

+2

क्या कुछ ऐसा ही है लेकिन अपरिवर्तनीय है? – barroco

+0

@ isola009: नहीं ... लाइब्रेरी एपीआई दस्तावेज़ों की जांच करें: http://www.scala-lang.org/api/current/index.html –

4
var eti = a.toList.reverse.iterator 
2

हैं आप अपने तत्वों को उनके द्वारा डाले गए क्रम में पुनर्प्राप्त करना चाहते हैं, आपको पहले-इन-फर्स्ट-आउट संग्रह की आवश्यकता है, इसलिए बस Queue का उपयोग करें।

import collection.mutable.Queue 

val queue = Queue(1,2,3) 
queue += 5 
queue += 4 

for(i <- queue) 
    println(i) 

प्रिंट

1 
2 
3 
5 
4 
+0

मुझे अपरिवर्तनीय संग्रह की आवश्यकता है, मेरा समाधान अच्छा है। धन्यवाद! – barroco

+0

एक अपरिवर्तनीय कतार 'scala.collection.immutable.Queue' –

+1

भी है कि एक कतार सेट नहीं है। एक कतार विशिष्टता की गारंटी नहीं देती है, और समानता पुनरावृत्ति आदेश पर निर्भर करती है। –

संबंधित मुद्दे