scala中的clojure迭代等价物?
递归很酷,但当您被高阶库函数包围时,它的级别有点低。我试图避免为依赖于最后生成的值的进程编写递归函数 我通常会在Clojure中的最后一个值和当前参数的“压缩”列表上使用函数。Scala的集合API中是否有等效函数 下面是一些疯狂的伪代码中的一个抽象示例: 说你有scala中的clojure迭代等价物?,scala,clojure,Scala,Clojure,递归很酷,但当您被高阶库函数包围时,它的级别有点低。我试图避免为依赖于最后生成的值的进程编写递归函数 我通常会在Clojure中的最后一个值和当前参数的“压缩”列表上使用函数。Scala的集合API中是否有等效函数 下面是一些疯狂的伪代码中的一个抽象示例: 说你有 输入列表:Seq(1,2,3) 对生成的最后一个值和列表中的下一项执行的某些操作: lastValue^2+nextInt(i) 您希望累积生成的所有值 我尽量避免写类似以下的东西: def f(ls:Seq[Int]):Seq[
- 输入列表:
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”在迭代器
上返回一组结果。实际上,我是通过查找制表
方法找到它的,我认为它应该在同一个位置。我建议使用迭代器
而不是流
,因为它不缓存计算值(这里不需要).没错。我之前在阅读有关此方法的文章时,正试图解释它为什么被称为“左扫描”。但对于它为什么被命名为“左扫描”仍有点不确定