単純なアプローチでは、必要なインデックスの算術シーケンスを生成し、それをストリームにマッピングします。適用方法は、対応する値を引き出すであろう:
def f[A](s:Stream[A], n:Int) =
0 until n map (i => Iterator.iterate(0)(_+n) map (s drop i))
f(Stream from 1, 3) map (_ take 4 mkString ",")
// Vector(1,4,7,10, 2,5,8,11, 3,6,9,12)
次の方法単純算術シーケンス内の次のインデックスでストリームから値を返すイテレータ採用するであろうよりパフォーマンス溶液:
def comb[A](s:Stream[A], first:Int, step:Int):Iterator[A] = new Iterator {
var i = first - step
def hasNext = true
def next = { i += step; s(i) }
}
def g[A](s:Stream[A], n:Int) =
0 until n map (i => comb(s,i,n))
g(Stream from 1, 3) map (_ take 4 mkString ",")
// Vector(1,4,7,10, 2,5,8,11, 3,6,9,12)
を
あなたはこれが俳優向けだと言いましたが、もしこれがAkkaなら、round-robin routerを使うことができます。
更新:上記(明らかに間違っている)は、プログラムが実行されている限り多くの作業があると想定しているため、hasNextは常にtrueを返します。有限ストリームでも動作するバージョンのMikhailの答えを参照してください。
更新:Mikhailは、this answer to a prior StackOverflow questionは実際に有限ストリームと無限ストリームに効果があると判断しました(ただし、ほぼイテレータと同様に動作しないようです)。
はい、私はそれを考えました。私は俳優からの結果をマージする必要があり、問題は中間結果も多くのメモリを消費することであり、私はいくつかのアクターと同じ数のタスク/結果が必要であることを望んでいます。しかし、それにもかかわらず、以前のタスクの結果を再利用するためにアクターを改装することができました。ストリームを分割する簡単な方法がない場合は、この方法を採用します。 –