Fork me on GitHub

Hi Nathan and all, I posted the problem in the #beginner channel, but someone suggested that I ask here. (I actually played with specter a bit (love it) but this is well beyond my current abilities). At its simplest level, let’s say I have a ‘dumb’ container component, e.g.:

(defn my-component [content]
[:div content])
… and a (possibly arbitrarily nested) tree structure, e.g.
(def tree [["a" ["b" "c" "d"]] "e"])
What approach would you use to walk the tree, plug-in the component and its content to return something like this?
(def result [:div
             [:div "a"
              [:div "b"]
              [:div "c"]
              [:div "d"]]
             [:div "e"]])
(My naive implementation has the component recursively calling itself on the children, which I really don’t want.) Thanks so much in advance!


@cperrone what exactly are the rules you want to follow for the transformation?


looks like you wrap leaf values in :div, except for the case of "a"


which wraps it and the children


but "b" doesn't follow that same rule


Let me think. In this case, a contains b c d (which are siblings), e is at the same level of a


So the rule (I think) is the same. my-component should be able to “render” its content recursively. An input map with nested :children vector may work as well, if it makes it easier. The crux of the problem is that the container wraps arbitrary content (which may include child containers).


@cperrone this is pretty close to what you want:

(defn my-component [node]
  `[:div ~(:val node) ~@(:children node)])

(def tree [{:val "a" :children [{:val "b"} {:val "c"} {:val "d"}]} {:val "e"}])

(def NODES (recursive-path [] p (continue-then-stay :children ALL p)))

(transform [ALL NODES] my-component tree)


oh man, thank you so much. My kid just arrived, so I need to take a break, but I’ll definitely play with it later on.


the key is to have a consistent and regular structure to your data


yes, indeed. I love how declarative specter is by the way. It’s easy to see what’s going on. Ok, gotta go, but thank you again!