This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
if i have a form with lots of nested values and i want to gather all of the nodes that match some predicate, how do i do that? there's no tree-seq
, and pre/post walk work like in clojure, and the various find-next-* functions don't seem to go up unless i misread the docstring.
Hi again @UEENNMX0T! Here's what I came up with:
(require '[rewrite-clj.node :as n]
'[rewrite-clj.zip :as z])
(def some-code "(let [x {:a 1 :b 2 :c {:d {:e 3}}}])")
(def zloc (z/of-string some-code))
;; an example of a predicate
(defn keyword-node? [zloc]
(some-> zloc z/node n/keyword-node?))
;; little helper to find the way we'd like to
(defn find-pred [p? zloc]
;; use z/next to include all nodes
(z/find-next zloc z/next p?))
(->> zloc
z/up ;; start from root
(find-pred keyword-node?) ;; move to first match
(iterate #(find-pred keyword-node? %)) ;; iterate over all other matches
(take-while #(not (z/end? %))) ;; until we reach the end
(map z/string)) ;; and convert zloc as you see fit
;; => (":a" ":b" ":c" ":d" ":e")
How's that work for you?Oh interesting, so from the root, you step into each top level form and dive until your reach the end
I wonder if this could be generalized into a “tree-seq”
Thank you! I’ll give this a go and see how it works for me