2014-09-30 204 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