Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a Round Robin/Circular Queue available in Scala Collections

Tags:

Is there a Round Robin Queue available in Scala Collections?

I need to repeatedly iterate a list that circles through itself

val x = new CircularList(1,2,3,4) x.next (returns 1) x.next (returns 2) x.next (returns 3) x.next (returns 4) x.next (returns 1) x.next (returns 2) x.next (returns 3) 

... and so on

like image 930
user2780187 Avatar asked Nov 04 '13 16:11

user2780187


2 Answers

It's pretty easy to roll your own with continually and flatten:

scala> val circular = Iterator.continually(List(1, 2, 3, 4)).flatten circular: Iterator[Int] = non-empty iterator  scala> circular.take(17).mkString(" ") res0: String = 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 

There's also a continually method on Stream—just be careful not to hold onto a reference to the head of the stream if you're going to be generating lots of elements.

like image 193
Travis Brown Avatar answered Oct 24 '22 23:10

Travis Brown


You can very easily create a circular list using a Stream.

scala> val l = List(1, 2, 3, 4).toStream l: scala.collection.immutable.Stream[Int] = Stream(1, ?)  scala> def b: Stream[Int] = l #::: b b: Stream[Int]  scala> b.take(20).toList res2: List[Int] = List(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4) 

Edit: you want to make sure to define the repeated part beforehand, once and only once, to avoid blowing the heap (structural sharing in Stream). As in:

def circular[A](a: Seq[A]): Stream[A] = {   val repeat = a.toStream   def b: Stream[A] = repeat #::: b   b } 
like image 39
gourlaysama Avatar answered Oct 24 '22 22:10

gourlaysama