首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用clojure.zip实现步行/后行走遍历

如何使用clojure.zip实现步行/后行走遍历
EN

Stack Overflow用户
提问于 2016-09-29 10:41:46
回答 2查看 497关注 0票数 2

我不知道如何使用clojure.zip实现clojure.walk/postwalk函数:

代码语言:javascript
运行
复制
(clojure.walk/postwalk
   #(do (println %)
        %)
   [1
    [2 [3 4 5]]
    [6 [7 8]]])

产出:

代码语言:javascript
运行
复制
1
2
3
4
5
[3 4 5]
[2 [3 4 5]]
6
7
8
[7 8]
[6 [7 8]]
[1 [2 [3 4 5]] [6 [7 8]]]
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-09-29 12:14:56

代码语言:javascript
运行
复制
(defn postwalk [f loc]
  (let [loc (if-some [loc (z/down loc)]
              (loop [loc loc]
                (let [loc (postwalk f loc)]
                  (if-some [loc (z/right loc)]
                    (recur loc)
                    (z/up loc))))
              loc)]
    (z/replace loc (f (z/node loc)))))

=> (postwalk #(doto % prn) (z/vector-zip [1 [2 [3 4 5]] [6 [7 8]]]))
1
2
3
4
5
[3 4 5]
[2 [3 4 5]]
6
7
8
[7 8]
[6 [7 8]]
[1 [2 [3 4 5]] [6 [7 8]]]

编辑:对于预走,只需在下线前执行z/replace即可。

代码语言:javascript
运行
复制
(defn prewalk [f loc]
  (let [loc (z/replace loc (f (z/node loc)))]
    (if-some [loc (z/down loc)]
      (loop [loc loc]
        (let [loc (prewalk f loc)]
          (if-some [loc (z/right loc)]
            (recur loc)
            (z/up loc))))
      loc)))
票数 4
EN

Stack Overflow用户

发布于 2019-11-04 20:49:30

我相信还有一种更实用的方法来实现post顺序遍历,以保留拉链样式的导航:

代码语言:javascript
运行
复制
(defn post-zip
  [loc]
  ;; start from the deepest left child
  (loop [loc loc]
    (if (z/branch? loc)
      (recur (z/down loc))
      loc)))

(defn post-next
  [loc]
  (if-let [sib (z/right loc)]
    ;; if we have a right sibling, move to it's deepest left child
    (post-zip sib)
    ;; If there is no right sibling move up if possible
    (if-let [parent (z/up loc)]
      parent
      ;; otherwise we are done
      [(z/node loc) :end])))

这允许您以与普通拉链相同的方式进行条件修改(也就是说,您不必总是使用z/replace,有时只需调用post-next而不更改当前节点)。

给定这些辅助函数的postwalk的实现变得非常简单:

代码语言:javascript
运行
复制
(defn postwalk [f zipper]
  (loop [loc (post-zip zipper)]
    (if (z/end? loc)
      (z/node loc)
      (recur (post-next (z/replace loc (f (z/node loc))))))))

此解决方案还具有不引入可能使大树溢出堆栈的递归的优点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39768093

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档