【问题标题】:Combining Scala streams结合 Scala 流
【发布时间】:2014-09-30 15:04:02
【问题描述】:

我需要组合来自多个(可能是无限的)流的值,流的数量可能会有所不同;有时“从每个中提取一个”并将它们作为元组处理,有时将值交错。

示例输入可能是这样的:

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, ...

有没有标准的,甚至是内置的解决方案来组合Streams?

【问题讨论】:

    标签: scala stream


    【解决方案1】:

    我的解决方案与 Eastsun 的解决方案相同,但更容易理解:

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

    【讨论】:

    • 如果流不是无限的,也许flatMap(_.headOption)
    【解决方案2】:

    这里是:

    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)
    

    【讨论】:

    • 这确实更简洁,尽管对于未经训练的人来说可能更不可读......
    【解决方案3】:

    我想出的最好但看起来有点“拥挤”,好像我正在尝试编写流操作的教科书示例......

    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
    

    【讨论】:

      猜你喜欢
      • 2019-02-17
      • 2014-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多