40

我想在 scala 中使用 Stream 类来无限重复给定的列表。

例如列表 (1,2,3,4,5) 我想创建一个流给我 (1,2,3,4,5,1,2,3,4,5,1,2,3 ....)

这样我就可以包装 take 操作。我知道这可以通过其他方式实现,但出于某种原因我想这样做,只是幽默我:)

所以这个想法是,通过从某个列表创建的这个无限循环,我可以使用 take 操作,当它到达列表的末尾时,它会循环。

如何制作一个简单地重复给定列表的流?

4

5 回答 5

42

与@Eastsun 的非常相似,但更能透露一些意图。在 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)

或者,使用 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)
于 2010-01-20T08:19:09.123 回答
33

另一种方法是.toStream将输入的 与自身递归连接。那是,

scala> def xs: Stream[Int] = List(1, 2, 3).toStream #::: xs
xs: Stream[Int]

scala> xs.take(10).toList
res1: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1)
于 2013-02-01T15:09:38.953 回答
8

在 scala 2.8 中有一个使用 Stream#flatten 的简单方法

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)
于 2010-01-20T02:57:05.343 回答
5

这是一个不假设length有效的实现:

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)
}

对于任何Seq(包括List或什Stream至),这应该以恒定的时间运行,并且只会施加恒定的时间开销来填充每个元素。此外,它甚至适用于无限序列。因此,您可以调用rep无穷大Stream,结果Stream将等同于输入。

于 2010-01-20T02:14:56.920 回答
1

从优秀的Scala by Example一书第 12 章中公然窃取,并进行了一些修改:

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)

这适用于所有 Seq 类型(当然,除非它们不能被多次读取)。如果 .length 调用很慢,可能效率不高。在 Scala 2.7.7 中测试。

于 2010-01-19T23:25:02.907 回答