【问题标题】:Find all parents as walking through a tree找到所有的父母就像穿过一棵树
【发布时间】: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.walkSpector 无关。我正在寻找一个使用clojure.zip 并按照我在问题中定义的父级的答案,这只是loc 上方的关键字。因此,如果给parent-ofloc:f,我希望它返回:c

如果有人可以告诉我,作为评论,拉链不再真正使用,并说 clojure.walkSpector 是当前用于导航树木的最佳实践方式,那么这将有所帮助。

【问题讨论】:

标签: clojure zipper


【解决方案1】:

你为什么使用zip/left?节点的父节点正是它上面的节点,而不是它上面的节点,出于某种原因在左边。删除它就是您需要做的所有事情。

【讨论】:

  • 我知道从技术上讲zip/up 给了父母。但父母永远只是封闭的向量。我需要(我相信)是这个封闭向量的第一个元素。这就是为什么在我的问题中我说:e 的父级是:b,尽管从技术上讲:e 的父级是[:b [:d] [:e]]
  • 如果您只需要节点的标签而不需要其结构,请在 (z/loc (z/up loc)) 的结果上调用 first
【解决方案2】:

这是我自己的答案:

(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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多