2014-09-30 3 views
1

Мне нужно объединить значения из нескольких (возможно, бесконечных) потоков, количество потоков может варьироваться; иногда «рисовать один из каждого» и обрабатывать их как кортеж, иногда чередуя значения.Объединение потоков Scala

вход образца может быть таким:

val as= Stream.from(0) 
val bs= Stream.from(10) 
val cs= Stream.from(100) 
val ds= Stream.from(1000) 
val list= List(as, bs, cs, ds) 

Для первого случая использования, я хотел бы в конечном итоге с чем-то вроде

Seq(0, 10, 100, 1000), Seq(1, 11, 101, 1001), ... 

и второй

Seq(0, 10, 100, 1000, 1, 11, 101, 1001, ... 

Есть ли стандартное или даже встроенное решение для объединения Stream s?

ответ

3

Мое решение совпадает с решением от Eastsun, но легче понять:

def combine[A](s:Seq[Stream[A]]):Stream[Seq[A]]=s.map(_.head) #:: combine(s.map(_.tail)) 
+0

Может быть, 'flatMap (_. headOption)' в случае, если потоки не бесконечны? – Thilo

0

Лучшее, что я придумал еще выглядит немного «людно», как будто я пытаюсь написать хрестоматийный пример потоковых операций ...

def combine[A](list: List[Stream[A]]): Stream[Seq[A]] = { 
    val listOfSeqs= list.map(_.map(Seq(_))) // easier to reduce when everything are Seqs... 
    listOfSeqs.reduceLeft((stream1, stream2)=> stream1 zip stream2 map { 
     case (seq1, seq2) => seq1 ++ seq2 
    }) 
} 

def interleave[A](list: List[Stream[A]]): Stream[A] = combine(list).flatten 
1

Вот оно:

scala> val coms = Stream.iterate(list)(_ map (_.tail)) map (_ map (_.head)) 
coms: scala.collection.immutable.Stream[List[Int]] = Stream(List(0, 10, 100, 1000), ?) 

scala> coms take 5 foreach println 
List(0, 10, 100, 1000) 
List(1, 11, 101, 1001) 
List(2, 12, 102, 1002) 
List(3, 13, 103, 1003) 
List(4, 14, 104, 1004) 

scala> val flat = coms.flatten 
flat: scala.collection.immutable.Stream[Int] = Stream(0, ?) 

scala> flat take 12 toList 
res1: List[Int] = List(0, 10, 100, 1000, 1, 11, 101, 1001, 2, 12, 102, 1002) 
+0

это гораздо более емким, на самом деле, хотя Perhap s даже менее читаемый для неподготовленного глаза ... – lre

Смежные вопросы