scala中的clojure迭代等价物?

scala中的clojure迭代等价物?,scala,clojure,Scala,Clojure,递归很酷,但当您被高阶库函数包围时,它的级别有点低。我试图避免为依赖于最后生成的值的进程编写递归函数 我通常会在Clojure中的最后一个值和当前参数的“压缩”列表上使用函数。Scala的集合API中是否有等效函数 下面是一些疯狂的伪代码中的一个抽象示例: 说你有 输入列表:Seq(1,2,3) 对生成的最后一个值和列表中的下一项执行的某些操作: lastValue^2+nextInt(i) 您希望累积生成的所有值 我尽量避免写类似以下的东西: def f(ls:Seq[Int]):Seq[

递归很酷,但当您被高阶库函数包围时,它的级别有点低。我试图避免为依赖于最后生成的值的进程编写递归函数

我通常会在Clojure中的最后一个值和当前参数的“压缩”列表上使用函数。Scala的集合API中是否有等效函数

下面是一些疯狂的伪代码中的一个抽象示例:

说你有

  • 输入列表:
    Seq(1,2,3)
  • 对生成的最后一个值和列表中的下一项执行的某些操作:

    lastValue^2+nextInt(i)

您希望累积生成的所有值

我尽量避免写类似以下的东西:

def f(ls:Seq[Int]):Seq[Float] = {

  def g(pos:Int, lastGen:Float):Seq[Float] = { 
    val v = gen(lastGen, ls(pos))
    if( end(v) )
      Seq(v)
    else
      Seq(v) ++ g(pos+1, v)
  }

  f(0, 1)
}

我在Haskell中定义Fibonacci的惰性流版本时也看到了类似的情况,所以假设我可以使用一个引用自身的惰性流,但这比Clojure的迭代更难让我的大脑思考。

这就是你要找的吗?这与Clojure中的内容基本相同:

List.iterate(1, 5) { _ + 1 }
// res1: List[Int] = List(1, 2, 3, 4, 5)
我认为
List
iterate
的定义来自

唯一的缺点是第二个参数
len
是您想要的参数数量,因此它不会像Clojure中的
iterate
那样返回无限序列

更新:

刚刚学到了一些新东西!该对象也有一个
iterate
方法,这使您可以创建无限的惰性流:

(Stream.iterate(1) { _ * 2 } take 5).toList
// res1: List[Int] = List(1, 2, 4, 8, 16)

您显示的代码基本上相当于:

ls.foldLeft(List(1.0))((a, b) => gen(a.head, b) :: a).reverse

这听起来像是你想要的高阶函数,它就像一个折叠,可以记住中间的步骤。例如,假设您拥有以下各项:

val ls = Seq(1, 2, 3)
def gen(lastValue: Double, n: Int) = math.pow(lastValue, 2) + n
然后您可以像这样将它们与
scanleet
组合:

scala> ls.scanLeft(1.0)(gen)
res0: Seq[Double] = List(1.0, 2.0, 6.0, 39.0)

这或多或少相当于Apocalisp在
foldLeft
中的公式,除了
scanLeft
为您保留中间值。

对不起,我应该在google之外搜索,直接在scala api中搜索。我以后会尝试问一些不太明显的问题(:别担心。我花了一段时间才找到它,而且我已经知道它的存在。在我看来,Scala API有点让人困惑,尤其是在所有隐式转换中。你实际上无法在列表的API页面上找到“iterate”,只需在谷歌上搜索“iterate”在
迭代器
上返回一组结果。实际上,我是通过查找
制表
方法找到它的,我认为它应该在同一个位置。我建议使用
迭代器
而不是
,因为它不缓存计算值(这里不需要).没错。我之前在阅读有关此方法的文章时,正试图解释它为什么被称为“左扫描”。但对于它为什么被命名为“左扫描”仍有点不确定