Fork me on GitHub
#specter
<
2018-06-24
>
pepe14:06:44

Hello, I have this 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}]
And I would like to traverse all the :val for :id = 1 and all its descendants. Is it possible with specter?

nathanmarz15:06:21

@pepe yes, you can do it with zippers

pepe15:06:03

Is it that I have to first compose the tree first then?

nathanmarz15:06:23

one sec I'll show you

4
nathanmarz15:06:33

@pepe

(use 'com.rpl.specter)
(require '[com.rpl.specter.zipper :as z])

(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}])

(def TO-GRAPH (path z/VECTOR-ZIP z/DOWN))
(defn to-node [id]
  (z/find-first #(= (:id %) id))
  )

(def CHILDREN
  (path
    (collect-one z/NODE :id)
    z/LEFTMOST
    z/NEXT-WALK
    (collect-one z/NODE :parent-id)
    (collected? [id1 id2] (= id1 id2))
    DISPENSE
    ))

(def DESCENDANTS (recursive-path [] p (stay-then-continue CHILDREN p)))

(select [TO-GRAPH (to-node 1) DESCENDANTS z/NODE (must :val)] data)

nathanmarz15:06:47

that said, it's a really bad representation for a tree

pepe15:06:31

You mean my data? Yeah, some legacy stuff. I will try it and report back. Thank you very much for help!

pepe16:06:02

On some bigger trees I am getting Maximum call stack size exceeded in CLJS. Indeed this representation is bad 😞

pepe16:06:23

The thing as always, is that those data I am receiving from API. The call stack is exceeded in the recursive-path

nathanmarz18:06:59

@pepe you can do better with custom navigators rather than zippers

nathanmarz18:06:03

navigate to pair of [list-of-nodes index], and then make custom CHILDREN navigator that does the search for indices that are direct children of currently navigated index

pepe06:06:56

Thank you very much! I think it is little bit over my Specter-fu, but I will try.