Say I have a tree where I want to visit - and that should include the possibility to modify the visited items - all items that match the path
(def visit-path [:b :all :x :all])
where I use :all as a wildcard to match all child nodes. In the following example tree,
(def my-tree
{:a "a"
:b
{:b-1
{:x
{:b-1-1 "b11"
:b-1-2 "b12"}}
:b-2
{:x
{:b-2-1 "b21"}}}})
that would be items
- [:b-1-1 "b11"]
- [:b-1-2 "b12"]
- [:b-2-1 "b21"]
Is there an elegant way to do this using clojure core?
FYI, I did solve this by creating my own pattern-visitor
(defn visit-zipper-pattern
[loc pattern f]
but although this function is generically usable, it is quite complex, combing both stack-consuming recursion and tail-call recursion. So when calling that method like
(visit-zipper-pattern (map-zipper my-tree) visit-path
(fn [[k v]] [k (str "mod-" v)]))
using map-zipper from https://stackoverflow.com/a/15020649/709537, it transforms the tree to
{:a "a"
:b {:b-1
{:x
{:b-1-1 "mod-b11"
:b-1-2 "mod-b12"}}
:b-2
{:x
{:b-2-1 "mod-b21"}}}}