【发布时间】:2016-09-02 14:18:04
【问题描述】:
我想使用clojure.zip 遍历这棵树并打印节点及其父节点。我很难找到父母。例如:e 的父级是:b。
;;
;; :a
;; / \
;; :b :c
;; /\ \
;; :d :e :f
;;
(def example [:a [:b [:d] [:e]] [:c [:f]]])
(def z (zip/vector-zip example))
(def locs (take-while (complement zip/end?) (iterate zip/next z)))
(defn parent-of [loc]
(when-let [parent-loc (-> loc zip/up zip/left)]
(zip/node parent-loc)))
(defn visit-all []
(doseq [loc locs]
(let [node (zip/node loc)]
(when (keyword? node)
(println node "has parent" (parent-of loc))))))
这是结果:
:a has parent nil
:b has parent :a
:d has parent :b
:e has parent [:d]
:c has parent [:b [:d] [:e]]
:f has parent :c
我可以继续改进parent-of 函数——我的下一个想法是转到最左边的节点。将有一个算法可以从所有位置返回正确答案 - 但是以这种方式进行似乎对于一个常见的要求来说需要做很多工作。
我应该采取更好的方法吗?
编辑
这个问题与clojure.walk 或Spector 无关。我正在寻找一个使用clojure.zip 并按照我在问题中定义的父级的答案,这只是loc 上方的关键字。因此,如果给parent-of 的loc 是:f,我希望它返回:c。
如果有人可以告诉我,作为评论,拉链不再真正使用,并说 clojure.walk 或 Spector 是当前用于导航树木的最佳实践方式,那么这将有所帮助。
【问题讨论】:
-
您能否为您尝试实现的功能提供示例输入和输出?