2014-09-30 134 views
1

我需要結合幾個(可能無限)流的值,流的數量可能會有所不同;有時候是爲了「從每個中抽取一個」並將它們作爲一個元組來處理,有時會交織這些值。組合斯卡拉流

樣品輸入可以是這樣的:

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

回答

3

我的解決方法是相同的,從東日的解決方案,但更容易理解:

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

也許'flatMap(_。headOption)'在流不是無限的情況下? – Thilo 2016-09-11 06:52:03

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對於未經訓練的眼睛來說,它更不可讀... – lre 2014-10-02 09:25:39