Proste podejście polega na wygenerowaniu sekwencji arytmetycznej dla indeksów, które chcesz, a następnie odwzorowaniu ich na strumień. Sposób stosuje się wyciągnąć odpowiednie wartości:
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)
bardziej wydajnych rozwiązanie wykorzystują iterację którego Kolejna metoda po prostu powraca do wartości od strumienia podczas następnego indeksu arytmetycznej sekwencji:
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)
Wspomniałeś, że to było dla aktorów, chociaż - jeśli to Akka, być może mógłbyś użyć round-robin router.
AKTUALIZACJA: Powyższe (najwyraźniej niepoprawnie) zakłada, że może być więcej pracy do wykonania, dopóki program jest uruchomiony, więc hasNext zawsze zwraca true; zobacz odpowiedź Mikhaila na wersję, która działa również z skończonymi strumieniami.
AKTUALIZACJA: Mikhail orzekł, że w rzeczywistości this answer to a prior StackOverflow question ma odpowiedź, która działa dla strumieni skończonych i nieskończonych (chociaż nie wygląda na to, że działałaby prawie tak dobrze jak iterator).
Tak, pomyślałem o tym. Muszę połączyć wyniki z aktorami, a problem polega na tym, że wyniki pośrednie pochłaniają też dużo pamięci i chcę, żeby było kilku aktorów i tyle samo zadań/wyników.Mimo to mogłem zmodernizować aktorów, aby ponownie wykorzystać wyniki z poprzednich zadań i pójdę tą drogą, jeśli nie ma prostego sposobu na podzielenie strumienia. –