I want to use clojure.zip to walk through this tree and print the node and its parent. I am having trouble getting the parent. For example the parent of :e is :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))))))
This is the result:
: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
I could keep improving the parent-of function - my next thought would be to go to the left-most node. There will be an algorithm that will return the correct answer from all locations - however going about it this way seems like quite a lot of work for a common requirement.
Is there a better approach I should be taking?
Edit
This question is not about clojure.walk or Spector. I am looking for an answer that uses clojure.zip and gives the parent as I defined it in the question, which is simply the keyword above the loc. So if the loc given to parent-of is :f I would expect it to return :c.
If someone can tell me, as a comment, that zippers are not really used anymore, and say clojure.walk or Spector is the current best practice way to go for navigating trees, then that would help.