specter

Latest version: 1.1.3
pepe 2018-06-25T06:14:56.000227Z

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

nathanmarz 2018-06-25T11:18:27.000309Z

@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)))

1
pepe 2018-06-26T11:35:11.000170Z

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!

pepe 2018-06-25T12:52:30.000399Z

@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.

2018-06-25T13:15:54.000085Z

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"}}]}]}
?

nathanmarz 2018-06-25T13:20:32.000800Z

@firstclassfunc is the transformation vector -> map and list -> vector for all reachable vectors and lists?

2018-06-25T13:21:01.000526Z

yes

nathanmarz 2018-06-25T13:29:12.000172Z

oh it's a little more complicated

nathanmarz 2018-06-25T13:29:47.000049Z

since the :slot and :port vectors get combined into a single map

2018-06-25T13:30:06.000770Z

ok well it can be done in multiple steps..

nathanmarz 2018-06-25T13:30:28.000310Z

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
  )

nathanmarz 2018-06-25T13:30:36.000556Z

you fill in the vec->map function

2018-06-25T13:30:50.000040Z

ah cool. Thanks so much (y)