繁体   English   中英

在Clojure中递归遍历向量

[英]Recursively run through a vector in Clojure

我才刚开始和Clojure一起玩。

如何遍历项目向量?

我幼稚的递归函数将具有类似于经典地图的形式。

(defn map [f xs] (
  (if (= xs [])
      []
      (cons (f (first xs)) (map f (rest xs))
  )
))

问题是我在网络上找不到此类代码的任何示例。 我发现了很多使用内置序列遍历功能的示例,例如for,map和loop。 但是没有人做原始的递归版本。

那是因为您不应该在Clojure中做这种事情吗? (例如,因为它使用了没有尾部调用优化之类的较低级Java原语?)?

当您说“遍历向量”时,这是非常模糊的; 由于Clojure是一门轻率的工具,因此专门研究序列分析和操作,因此使用这种语言的好处在于,您不会以“遍历向量然后对每个元素进行处理”的方式来思考,相反,您会习惯地说“将其从向量中抽出”或“将该向量转换为X”或“我希望该向量给我X”。

正是由于使用Lisp语言的这种观点,您将看到很多示例和生产代码,它们不仅循环/重复通过向量,而且还专门以简短,惯用的方式进行处理。 使用简单的函数(如reduce map filter for into和其他函数),您可以优雅地在诸如矢量之类的序列上移动, 同时对内容进行所需的处理。 在大多数其他语言中,这至少是两个不同的部分:循环,然后是执行所需操作的实际逻辑。

您会经常发现,如果使用C,C ++,Java等语言获得的更命令性的思想来考虑序列,那么您的代码(至少)比起初考虑时要长大约4倍。以更实用的方式制定您的计划。

Clojure 仅在使用尾递归时才重用堆栈帧,并且仅在使用显式recur调用时才重用 其他所有内容都将消耗堆栈。 上面的地图示例不是尾部递归,因为缺点是在递归调用之后发生的,因此不能以任何语言进行TCO。 如果您将其切换为使用延续传递样式并使用显式调用来代替map进行recur ,那么您应该很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM