specter

nathanmarz 2024-02-12T01:37:02.567719Z

@pranav.ram7 check out this page https://github.com/redplanetlabs/specter/wiki/Using-Specter-Recursively

Pranav Ram 2024-02-14T07:20:06.736169Z

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 []}