tags:

views:

117

answers:

6
+2  Q: 

Ordered ListSet

ListSet (collection.immutable.ListSet) is a inverse ordered set. I need ordered set. This is a example of original ListSet:

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

And this is a example of I need:

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

UPDATE:

"Ordered" is a "Insertion Ordered" for me. I need this:

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  A: 

Actually, it's not an ordered set at all. If you need order, use an implementation of immutable.SortedSet, such as immutable.TreeSet.

Matthew Flaschen
The OP clarified that he meant "insertion-ordered" rather than "ordered".
Aaron Novstrup
@anov, I see that. However, I don't know a solution to the new version of the question.
Matthew Flaschen
+1  A: 

It is not ordered:

val a = ListSet(3,1,2)
val ite = a.iterator
ite.next // returns 2
ite.next // returns 1
ite.next // returns 3
Daniel
@Daniel, Yes!, These is not ordered. Why?
isola009
@isola009 A `Set` is not ordered. A `ListSet` is a `Set` backed by a `List`, and the optimal way to add stuff to a `List` is prepend elements. Therefore, the last element added to the `List` backing the `Set` will be the first element of that `List`, which causes the behavior you see when you use `iterator`.
Daniel
+3  A: 

collection.mutable.LinkedHashSet is a set that iterates its members in the same sequence they were inserted. (I avoid the term "ordered" here, since I prefer to reserve that to cases of an ordering relation on the values, not the particular sequence in which some actions were carried out.)

Randall Schulz
Is there something similar but immutable?
isola009
@isola009: No. ... You know, if you ask nicely, they'll let you peruse the library API docs yourself: http://www.scala-lang.org/api/current/index.html
Randall Schulz
+2  A: 
var eti = a.toList.reverse.iterator
user unknown
A: 
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
  }

}
isola009
+2  A: 

If you want to retrieve your elements in the order they were inserted, you need a first-in-first-out collection, so simply use a Queue.

import collection.mutable.Queue

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

for(i <- queue)
  println(i)

prints

 1
 2
 3
 5
 4
Mr_Qqn
I need immutable collection, my solution is cool. Thanks!
isola009
There's also an immutable queue `scala.collection.immutable.Queue`
Mr_Qqn