【问题标题】:clojure iterate equivalent in scala?clojure在scala中迭代等效?
【发布时间】:2012-08-23 03:41:03
【问题描述】:

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

我通常会在 Clojure 中使用 iterate 函数,而不是最后一个值和当前参数的“压缩”列表。 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 的迭代相比,这更难让我的大脑思考。

【问题讨论】:

    标签: scala clojure


    【解决方案1】:

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

    List.iterate(1, 5) { _ + 1 }
    // res1: List[Int] = List(1, 2, 3, 4, 5)
    

    我认为iterate对于List的定义来自GenTraversableFactory

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

    更新:

    刚学到新东西! Stream 对象也有一个 iterate 方法,这可以让你创建无限的惰性流:

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

    【讨论】:

    • 对不起,我应该直接在 scala api 中搜索 Google 之外的内容。我将来会尝试问不太明显的q(:
    • 别担心。我花了一段时间才找到它——而且我已经知道它的存在。在我看来,Scala API 有点令人困惑,尤其是所有隐式转换。您实际上无法在 List 的 API 页面上找到“迭代”,而只是在谷歌上搜索“迭代”会在 Iterator 上返回一堆结果。我实际上是通过寻找 tabulate 方法找到的,我认为它会在同一个地方。
    • 我推荐使用Iterator 而不是Stream,因为它不会缓存计算的值(这里不需要)。
    【解决方案2】:

    你展示的代码基本上相当于:

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

    【讨论】:

      【解决方案3】:

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

      val ls = Seq(1, 2, 3)
      def gen(lastValue: Double, n: Int) = math.pow(lastValue, 2) + n
      

      然后你可以像这样将它们与scanLeft结合起来:

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

      这或多或少等同于 Apocalisp 的 foldLeft 公式,只是 scanLeft 负责为您保留中间值。

      【讨论】:

      • 完全正确。当我之前阅读此方法时,我试图破译为什么它被称为左扫描。为什么它如此命名仍然有点不稳定
      猜你喜欢
      • 2013-02-14
      • 2011-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-13
      • 1970-01-01
      • 2016-06-05
      相关资源
      最近更新 更多