¿Hay algún Round Robin/Circular Queue disponible en Scala Collections?
scala-collections scala-2.10 (4)
Es bastante fácil rodar los tuyos continually
y 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
También hay un método continually
en Stream
tenga cuidado de no aferrarse a una referencia a la cabecera del stream si va a generar muchos elementos.
¿Hay algún Round Robin Queue disponible en Scala Collections?
Necesito repetir repetidamente una lista que circula a través de sí misma.
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)
... y así
Esto es feo en tener un índice mutable externo, pero hace lo que se solicita:
scala> var i = 0
scala> val ic4 = Iterator.continually { val next = IndexedSeq(1, 2, 3, 4)(i % 4); i += 1; next }
i: Int = 0
ic4: Iterator[Int] = non-empty iterator
scala> ic4 take 10 foreach { i => printf("ic4.next=%d%n", i) }
ic4.next=1
ic4.next=2
ic4.next=3
ic4.next=4
ic4.next=1
ic4.next=2
ic4.next=3
ic4.next=4
ic4.next=1
ic4.next=2
Al menos ilustra Iterator.continually
. También está Stream.continually
, que tiene la misma firma.
Puede crear fácilmente una lista circular utilizando un 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)
Edición : desea asegurarse de definir la parte repetida de antemano, una y solo una vez, para evitar volar el montón (compartición estructural en Stream
). Como en:
def circular[A](a: Seq[A]): Stream[A] = {
val repeat = a.toStream
def b: Stream[A] = repeat #::: b
b
}
Versión más concentrada en conseguir nuevos elementos en cada ejecución.
val getNext: () => Int = {
def b: Stream[Int] = List(1, 2, 3, 4).toStream #::: b
var cyclicIterator: Stream[Int] = b
() => {
val tail = cyclicIterator.tail
val result = tail.head
cyclicIterator = tail
result
}
} // could be written more sexy?
En tu problema puedes usarlo como:
for(i<- 1 to 10) yield getNext()