list scala stream infinite

Scala, repite infinitamente una lista finita.



stream infinite (5)

Aquí hay una implementación que no asume que la length es eficiente:

def rep[A](seq: Seq[A]) = { def inner(proj: Seq[A]): Stream[A] = { if (proj.isEmpty) inner(seq) else Stream.cons(proj.first, inner(proj drop 1)) } if (seq.isEmpty) Stream.empty else inner(seq) }

Esto debería ejecutarse en tiempo constante para cualquier Seq (incluida la List o incluso Stream ) y solo impone una sobrecarga de tiempo constante para completar cada elemento. Además, funciona incluso para secuencias infinitas. Por lo tanto, puede llamar a rep en un Stream infinito y el Stream resultante será equivalente a la entrada.

Quiero usar la clase Stream en Scala para repetir una lista dada de manera infinita.

Por ejemplo, la lista (1,2,3,4,5) quiero crear una secuencia que me dé (1,2,3,4,5,1,2,3,4,5,1,2,3). ....)

Para que yo pueda envolver la toma de operación. Sé que esto se puede implementar de otras maneras, pero quiero hacerlo de esta manera por alguna razón, solo hazme el humor :)

Entonces, la idea es que con este ciclo infinito creado a partir de alguna lista, puedo usar la operación de toma, y ​​cuando llega al final de la lista, se cicla.

¿Cómo hago una transmisión que simplemente repite una lista dada?


Hay una manera simple con Stream # flatten in scala 2.8

Welcome to Scala version 2.8.0.r20542-b20100116020126 (Java HotSpot(TM) Client VM, Java 1.6.0_18). Type in expressions to have them evaluated. Type :help for more information. scala> def cycle[T](seq: Seq[T]) = Stream.from(0).flatten(_ => seq) cycle: [T](seq: Seq[T])scala.collection.immutable.Stream[T] scala> cycle(1::2::3::Nil) res0: scala.collection.immutable.Stream[Int] = Stream(1, ?) scala> res0.take(10) res1: scala.collection.immutable.Stream[Int] = Stream(1, ?) scala> res0.take(10).toList res2: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1)


Muy similar a la de @ Eastsun, pero un poco más reveladora de intenciones. Probado en Scala 2.8.

scala> val l = List(1, 2, 3) l: List[Int] = List(1, 2, 3) scala> Stream.continually(l.toStream).flatten.take(10).toList res3: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1)

Alternativamente, con Scalaz:

scala> import scalaz._ import scalaz._ scala> import Scalaz._ import Scalaz._ scala> val l = List(1, 2, 3) l: List[Int] = List(1, 2, 3) scala> l.toStream.repeat[Stream].join.take(10).toList res7: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1)


Robado descaradamente del excelente libro Scala by Example , capítulo 12, y con algunas modificaciones:

def repeatedSeq(idx: Int, lst:Seq[Int]): Stream[Int] = Stream.cons(lst(idx), repeatedSeq((idx + 1)%lst.length, lst)) for(i <- repeatedSeq(1,List(1,1,2,3,5))) println(i)

Esto funciona para todos los tipos de secuencias (a menos que no puedan leerse varias veces, por supuesto). Podría no ser eficiente si la llamada .length es lenta. Probado en Scala 2.7.7.


Un método alternativo es concatenar el .toStream de la entrada consigo mismo recursivamente. Es decir,

scala> val xs: Stream[Int] = List(1, 2, 3).toStream #::: xs xs: Stream[Int] = Stream(1, ?) scala> xs.take(10).toList res1: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1)