40

ScalaでStreamクラスを使用して、指定されたリストを無限に繰り返したいと思います。

たとえば、リスト(1,2,3,4,5)を作成して、(1,2,3,4,5,1,2,3,4,5,1,2,3)を取得します。 ....)

テイク操作をラップできるようにします。私はこれが他の方法で実装できることを知っています、しかし私は何らかの理由でそれをこのようにしたいと思います、ただ私をユーモアを交えてください:)

つまり、あるリストから作成されたこの無限のサイクルで、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 book の第 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 に答える