Fork me on GitHub
#specter
<
2023-11-29
>
itaied11:11:57

another question, how would you write this: (take the key of map represented as vector into the value as the key :name. it's a nested structure)

{:id 0
 :children [:child-1 {:id 1}
            :child-2 {:id 2
                      :children [:child-3 {:id 3}]}]}
to:
{:id 0
 :children [:child-1 {:id 1 :name :child-1}
            :child-2 {:id 2 :name :child-2
                      :children [:child-3 {:id 3 :name :child-3}]}]}

rolt07:11:28

a way to collect the name to apply to the node: [(view #(apply hash-map %)) ALL (collect-one FIRST) LAST] a way to navigate to every node:

(recursive-path [] p
(if-path #(and (map? %) (contains? % :children))
(stay-then-continue :children (view #(apply hash-map %)) MAP-VALS p) STAY))
combining the two:
(def nodes
(recursive-path [] p
(if-path #(and (map? %) (contains? % :children))
(stay-then-continue :children (view #(apply hash-map %)) ALL DISPENSE (collect-one FIRST) LAST p)
STAY)))

(transform nodes (fn ([v] v) ([c v] (assoc v :name c)))
{:id 0
 :children [:child-1 {:id 1}
            :child-2 {:id 2
                      :children [:child-3 {:id 3}]}]})

rolt08:11:04

I don't like the fact that I'm using stay twice 😕

itaied08:11:27

Yesterday I tried it without specter, and I'm not sure what I like better:

(defn attach-names [app]
  (if (:children app)
    (update app :children #(->> %
                                (partition 2)
                                (mapv (fn [[k v]] [k (assoc (attach-names v) :name k)]))
                                flatten
                                vec))
    app))

itaied08:11:19

I just couldn't wrap my head around how to do it with specter, and the way you wrote it doesn't seem to me straightforward as just "normal" clj code

rolt08:11:32

i think you can replace (mapv + flatten) by mapcat

👍 1
rolt08:11:28

you can also mix the two solutions: use clojure for recursion, and replace the update fn by (transform [(view #(partition 2 %) (collect-one FIRST) LAST] (fn [c v] (assoc v ;name c) ...)

rolt08:11:07

hmm no that would be even longer code