在Scala中,基于先前值和第二个流创建流

时间:2014-12-23 02:15:29

标签: scala stream

我无法想出将这些组合成单个流的方法。我有:

val loop: Stream[Bar] = Stream(bar1, bar2, bar3) #::: loop
val init: Foo = new Foo()
def nextFoo(foo: Foo, bar: Bar): Foo = { ... }

我想要的是这样的流:

Stream(
    init, 
    nextFoo(init, bar1), 
    nextFoo(nextFoo(init, bar1), bar2),
    nextFoo(nextFoo(nextFoo(init, bar1), bar2), bar3),
    nextFoo(nextFoo(nextFoo(nextFoo(init, bar1), bar2), bar3), bar1),
    ...
)

或者说,每个元素都依赖于loop中的下一个元素和输出流中的前一个元素。

这是一个鸡与蛋的问题 - 我觉得我想zip第二个流与第一个流,但我无法创建第一个流(例如,{{ 1}})没有压缩第二个。

仅仅使用Scala集合库中的函数是否可以实现?我可以把Stream.iterate放在一起但是如果可能的话就想避免这种情况。

1 个答案:

答案 0 :(得分:2)

"假" Bar和Foo将包含"处理过的"吧看起来像这样:

  case class Bar(s: String)
  val bar1 = Bar("bar1")
  val bar2 = Bar("bar2")
  val bar3 = Bar("bar3")

  case class Foo(bars: Seq[Bar])


  val loop: Stream[Bar] = Stream(bar1, bar2, bar3) #::: loop
  val init: Foo = new Foo(Nil)
  def nextFoo(foo: Foo, bar: Bar): Foo =
    foo.copy(bars = foo.bars :+ bar)

  val foos: Stream[Foo] = Stream(init) #::: foos.zip(loop).map({ case (f, b) => nextFoo(f, b) })

  foos.take(10).toList.foreach(println)

结果:

Foo(List())
Foo(List(Bar(bar1)))
Foo(List(Bar(bar1), Bar(bar2)))
Foo(List(Bar(bar1), Bar(bar2), Bar(bar3)))
Foo(List(Bar(bar1), Bar(bar2), Bar(bar3), Bar(bar1)))
Foo(List(Bar(bar1), Bar(bar2), Bar(bar3), Bar(bar1), Bar(bar2)))
Foo(List(Bar(bar1), Bar(bar2), Bar(bar3), Bar(bar1), Bar(bar2), Bar(bar3)))
Foo(List(Bar(bar1), Bar(bar2), Bar(bar3), Bar(bar1), Bar(bar2), Bar(bar3), Bar(bar1)))
Foo(List(Bar(bar1), Bar(bar2), Bar(bar3), Bar(bar1), Bar(bar2), Bar(bar3), Bar(bar1), Bar(bar2)))
Foo(List(Bar(bar1), Bar(bar2), Bar(bar3), Bar(bar1), Bar(bar2), Bar(bar3), Bar(bar1), Bar(bar2), Bar(bar3)))