Thank you very much! I think it is little bit over my Specter-fu, but I will try.
@pepe looks like
(use 'com.rpl.specter)
(def data
[{:id 0}
{:id 1}
{:id 2 :parent-id 1 :val 1}
{:id 3 :parent-id 1 :val 1}
{:id 4 :parent-id 2 :val 2}
{:id 5 :parent-id 3 :val 2}
{:id 6 :parent-id 3 :val 2}
{:id 7 :parent-id 0 :val 100}
{:id 8 :parent-id 7 :val 200}
{:id 9 :parent-id 6 :val 3}])
(defn- node-index [graph id]
(select-first
[INDEXED-VALS
(selected? LAST :id (pred= id))
FIRST]
graph
))
(defnav to-node [id]
(select* [this graph next-fn]
(if-let [i (node-index graph id)]
(next-fn [graph i])
NONE
))
(transform* [this graph next-fn]
(if-let [i (node-index graph id)]
(first (next-fn [graph i]))
graph
)))
(defn- child-indices [graph id]
(select
[INDEXED-VALS
(selected? LAST :parent-id (pred= id))
FIRST]
graph
))
(defnav CHILDREN []
(select* [this [graph i] next-fn]
(let [id (-> graph (nth i) :id)
child-i (child-indices graph id)]
(if (empty? child-i)
NONE
(doseq [i child-i]
(next-fn [graph i])
))))
(transform* [this [graph i] next-fn]
(let [id (-> graph (nth i) :id)
child-i (child-indices graph id)]
(if (empty? child-i)
[graph i]
[(reduce
(fn [graph ci] (first (next-fn [graph ci])))
graph
child-i
)
i]
))))
(defnav NODE []
(select* [this [graph i] next-fn]
(next-fn (nth graph i))
)
(transform* [this [graph i] next-fn]
[(transform (nthpath i) next-fn graph) i]
))
(def DESCENDANTS (recursive-path [] p (stay-then-continue CHILDREN p)))
I got to try it today and it again gives me Maximum call stack exceeded on around 1000 nodes. It seems I have to go recursive 🙂. Still thank you very much, I have learned a lot from your code!
@nathanmarz thank you very much for your time. I can't imagine coming with something like this myself. I will report back, how it works for me.
Morning. I am trying to convert the hiccup
output from instaparse
into an associative structure. Is specter
a good solution for converting
[:entity
([:name "J"]
[:locations
([:address [:slot "slot0"] [:port "1"]]
[:address [:slot "slot1"] [:port "2"]]
[:address [:slot "slot2"] [:port "3"]]
[:address [:slot "slot3"] [:port "4"]]
[:address [:slot "slot4"] [:port "5"]]
[:address [:slot "slot5"] [:port "6"]])])]
into {:entity
[{:name "J"}
{:locations
[{:address {:slot "slot0" :port "1"}}
{:address {:slot "slot1" :port "2"}}
{:address {:slot "slot2" :port "3"}}
{:address {:slot "slot3" :port "4"}}
{:address {:slot "slot4" :port "5"}}
{:address {:slot "slot5" :port "6"}}]}]}
?@firstclassfunc is the transformation vector -> map and list -> vector for all reachable vectors and lists?
yes
oh it's a little more complicated
since the :slot
and :port
vectors get combined into a single map
ok well it can be done in multiple steps..
but the general structure is
(def NODES
(recursive-path [] p
(if-path coll?
(continue-then-stay ALL p)
)))
(multi-transform
[NODES
(if-path vector?
(terminal vec->map)
(terminal vec)
)]
data
)
you fill in the vec->map
function
ah cool. Thanks so much (y)