4

乱数のシーケンスを生成する問題を考えてみましょう。最終的なシーケンスは固定長nでなければならず、前後の要素は異なる必要があります (つまり、隣接要素は異なる必要があります)。私の最初の慣用的なアプローチは次のようなものです。

val seq = Stream.continually{ Random.nextInt(10) }
                .foldLeft(Stream[Int]()){ (all: Stream[Int], next: Int) =>
                  if (all.length > 0 && all.last != next)
                    all :+ next
                  else
                    all
                }
                .take(n)

残念ながら、foldLeft は無限ストリーム全体を消費しようとするため、これは機能しません。その結果、無限ループが発生します。直感的に、この質問によれば、この動作はfoldRight? たぶん、私は別の慣用的な解決策を見逃していますか?

4

4 に答える 4

1

独自のヘッドでストリームを圧縮することは非常に優れたトリックですが、私はsliding演算子を好みます。

val s = Stream.continually { Random.nextInt(10) } sliding(2) collect { case Stream(a,b) if a!=b => a } take 100 

注意: Stream ではなく、これから Iterator を取得します。Stream はその結果を記憶します (したがって、複数回反復可能です)。イテレータは 1 回だけ反復可能です。

于 2013-07-01T13:43:07.077 に答える
1

では、これはどうですか:

scala> val M = 10
M: Int = 10

scala> val seq = Stream.iterate(Random.nextInt(M)){ x => 
         val nxt = Random.nextInt(M-1); if(nxt >= x) nxt + 1 else nxt 
       }
于 2013-07-01T14:18:08.667 に答える