Существует ли круглая круговая/круговая очередь в Scala Коллекциях - программирование
Подтвердить что ты не робот

Существует ли круглая круговая/круговая очередь в Scala Коллекциях

Существует ли очередь Round Robin Queue в Scala Коллекциях?

Мне нужно многократно перебирать список, который проходит через него

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)

... и т.д.

4b9b3361

Ответ 1

Довольно легко сворачивать свои собственные с помощью continually и 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

Также существует метод continually на Stream - просто будьте осторожны, чтобы не удерживать ссылку на головку потока, если вы собираетесь генерировать множество элементов.

Ответ 2

Вы можете легко создать круговой список, используя 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)

Изменить: вы хотите, чтобы определить повторяющуюся часть заранее, один раз и только один раз, чтобы избежать раздувания кучи (структурный обмен в Stream). Как в:

def circular[A](a: Seq[A]): Stream[A] = {
  val repeat = a.toStream
  def b: Stream[A] = repeat #::: b
  b
}

Ответ 3

Это уродливое наличие внешнего изменяемого индекса, но он делает то, что запрошено:

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

По крайней мере, это иллюстрирует Iterator.continually. Существует также Stream.continually, который имеет одну и ту же подпись.

Ответ 4

Версия больше сконцентрирована на получении нового элемента при каждом выполнении.

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?

В вашей проблеме вы можете использовать его как:

for(i<- 1 to 10) yield getNext()