I'm having trouble figuring out how to navigate to an entry that could have a variable number of steps. An individual navigate/transform is easy enough and looks something like this:
(sp/transform [(node-named "2002") :children (node-named "01") :expanded] invert test-tree)
However I need to be able to provide a path that could have from 1 to 4 entries. In the above example it would be ["2002" "01"]
. What would be the best way to approach this?
I tried building the navigator with for
in a let
statement like this:(defn toggle [tree path]
(let [nav (conj
(vec
(interpose :children (for [p path] (conj (seq [p]) 'node-named ))))
:expanded)]
(sp/transform nav invert tree)))
But although this gives me a value for nav
that looks exactly right, running it throws Not a navigator
errorstry something like this:
(defn navigator [strs]
(path (mapcat (fn [s] [:children ALL #(= (:name %) s)]) strs)))
also, the invert
function can be replaced with the core function not
🙂
@schmee That looks promising, thanks. I'm getting the right node back now. Just got to massage it a bit to toggle :expanded. Which I will do with not
😳
remember that you can compose paths with a simple vector:
(transform [(navigator ["2000" "01"]) :expanded] not test-tree)
yup, got it working now. Still waiting for the ah-ha moment with specter, but it is doing some useful things even though often I'm not entirely sure why....
stick with it! 🙂 like anything worth learning it takes practice but the payoff is worth it IMO
you can always ask here if you get stuck 👍
where node-named
invert
and test-tree
are:
(defn node-named [n]
(sp/walker #(= (:name %) n)))
(defn invert [b]
(if b false true))
(def test-tree
{:name "root"
:focus ["root"]
:expanded true
:children [{:name "2000"
:expanded true
:children [{:name "01"
:expanded true
:children [{:name "project-1"}
{:name "project-2"}]}
{:name "02"
:expanded true
:children [{:name "project-5"}
{:name "project-6"}]}]}
{:name "2002"
:expanded false
:children [{:name "01"
:expanded false
:children []}]}]})