@pranav.ram7 check out this page https://github.com/redplanetlabs/specter/wiki/Using-Specter-Recursively
Thanks Nathan! Made some progress on extracting the nodes and edges. Is this the correct use of threading transform and select? I think there's a more elegant approach that what I've tried.
(defn collect-nodes [data]
(let [path (specter/recursive-path [] p
(specter/stay-then-continue [:has-option specter/ALL p]))] ;; Define recursive path through :has-option
(specter/transform (specter/collect path)
(fn [nodes] (map #(dissoc % :has-option) nodes))
data)))
(defn extract-id-pairs [data]
(let [path (specter/recursive-path [] p
(specter/stay-then-continue [:has-option specter/ALL p]))] ;; Define recursive path through :has-option
(->> data
(specter/transform (specter/collect path)
(fn [nodes]
(map (fn [node]
(map (fn [child] {:source (:id node) :target (:id child)}) (:has-option node))) nodes)))
(specter/select [specter/ALL specter/ALL])
)))
input to both like so:
{:displayName "Debit Card",
:name "ATM Card",
:has-option
[{:name "Mastercard", :id "-2", :label "Mastercard", :values (), :has-option []}
{:name "Rupay", :id "-3", :label "Rupay", :values (), :has-option []}
{:displayName "Visa",
:name "Visa",
:has-option
[{:displayName "Debit Card Limits - International",
:name "International",
:has-option [],
:label "International",
:id "-5",
:values (),
:valuesMandatory false,
:levelDisplayName "Card Usage",
:splitNode false,
:attributes
[{:mandatory "Optional",
:numericType "Fixed",
:displayName "ATM per Day",
:name "ATM per Day",
:globalFieldName "ATM per Day",
:booleanValue true,
:productProcessorDataType "amount",
:facilityAtAccountOrProductLevel "Party",
:ppFieldName "ATM per Day",
:showAtProductCatalogLevel true,
:dataType "Number",
:lov [],
:defaultValue 0,
:apiLov {:lovs []}}]}
{:name "Domestic", :id "-6", :label "Domestic", :values (), :has-option []}],
:label "Visa",
:id "-4",
:values ("International" "Domestic"),
:valuesMandatory false,
:levelDisplayName "Type Of Debit Card",
:splitNode true,
:attributes
[{:mandatory "Mandatory",
:numericType "Fixed",
:displayName "Debit Card Short Name",
:name "Debit Card Short Name",
:globalFieldName "Debit Card Short Name",
:booleanValue true,
:productProcessorDataType "string",
:facilityAtAccountOrProductLevel "Account",
:ppFieldName "Debit Card Short Name",
:showAtProductCatalogLevel true,
:dataType "LOV",
:lov [],
:apiLov {:lovs []}}]}],
:label "ATM Card",
:id "-1",
:values ("Mastercard" "Rupay" "Visa"),
:valuesMandatory false,
:levelDisplayName "ATM Card",
:splitNode true,
:attributes []}