找到所有父母穿过树

时间:2016-09-02 14:18:05

标签: clojure zipper

我想使用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.walkSpector无关。我正在寻找一个使用clojure.zip的答案,并根据我在问题中定义的内容给出父母,这只是loc上方的关键字。因此,如果loc的{​​{1}}为parent-of,我希望它返回:f

如果有人可以告诉我,作为评论,拉链已经不再使用了,并说:cclojure.walk是当前导航树木的最佳做法,那么这将有所帮助。

2 个答案:

答案 0 :(得分:2)

您为什么使用zip/left?节点的父节点正好是它上面的节点,而不是它上面的节点和由于某种原因向左的节点。删除就是您需要做的全部。

答案 1 :(得分:0)

这是我自己的答案:

(defn parent-of [loc]
  (when-let [parent-loc (-> loc zip/up zip/up first)]
    (zip/node parent-loc)))

在所有情况下都能提供正确的输出:

:a has parent nil
:b has parent :a
:d has parent :b
:e has parent :b
:c has parent :a
:f has parent :c