转换为循环...重复递归

时间:2011-09-14 18:04:16

标签: clojure

据我所知,在不使用循环的情况下在Clojure中递归。对于短序列,recur语法可能不是问题。但是,使用loop .. recur语法是编写递归函数的首选方法。所以,我想从首选方法开始。

但是,我一直在努力转换这个函数[edit],它返回一个序列的骨架(没有它的值的序列结构)

(defn skl
  [tree]
  (map skl (filter seq? tree)))

使用此数据进行测试

(def test_data1 '(1 (2 3) ( ) (( )) :a))
(def test_data2 '(1 2 (3 4) (5 ( 6 7 8))))

循环..重复语法。任何有关示例的想法或指示都将受到赞赏。

3 个答案:

答案 0 :(得分:4)

循环和重复是简单迭代的转换。然而,下降到树本身是递归的。您必须手动维护堆栈才能将其转换为单个迭代。因此,您的代码无法进行“简单”转换。

答案 1 :(得分:3)

您可能需要查看拉链库,它允许良好的结构化树编辑,但它可能不如您的原始优雅。我几乎不需要使用循环...复发。几乎总是有一个更高阶的功能,以相同或更好的效率更优雅地解决问题。

map替换loop ... recur会使代码更加冗长,更不清晰。你也失去了分块序列的好处。

答案 2 :(得分:1)

看看clojure.walk来源。它是一个在所有Clojure嵌套数据结构上执行(批量)操作的库(不包括有序映射)。这里有一些非常强大但看似简单的代码,使用本地定义的匿名函数递归而不使用循环/重复。

其中的大多数功能都基于后走路和前走路功能,后者又基于步行功能。使用源代码和(prewalk-demo形式)和(postwalk-demo形式),您可以很好地了解所采取的递归步骤。

我不知道这是否可以帮助您解决问题。我正在尝试在同一个问题域中做一些事情:创建一个函数将“嵌套”嵌套映射和向量“展平”为从根到叶的所有路径的序列,每个路径都是一系列键和/或索引,以'叶的价值。

这个库似乎在整个结构中递归地编辑值非常简单。但是,我仍然不知道如何使用它在功能上跟踪我的“路径”所需的迭代之间的累积数据,也可能是你的“骨架”问题。