I have a graph in nested maps which I would like to turn into a set of edges with node ids, node labels and edge labels:
#{{:edge/from 17592186325348 :edge/to 17592186325351
:edge/label :A2
:edge/from_node_label "a" :edge/to_node_label "l"}}
Here, I have shown the desired format for the edge a->l
that appears twice in the datastructure below. The data structure starts with a "source node". Children encode other targets. :edge_label
is the label for the directed edge from the parent to the child.
I'm guessing that a recursive solution would be easiest?
{:db/id 17592186325353,
:predicate/children [{:db/id 17592186325357,
:predicate/children [{:db/id 17592186325348,
:predicate/children [{:db/id 17592186325351,
:predicate/children [],
:node_label "l",
:edge_label :A1}],
:node_label "a",
:edge_label :A2}],
:node_label "m",
:edge_label :A2}
{:db/id 17592186325348,
:predicate/children [{:db/id 17592186325351,
:predicate/children [],
:node_label "l",
:edge_label :A1}],
:node_label "a",
:edge_label :A1}],
:node_label "e"}
It is a graph, because there is a cycle at a.
However, for the purposes of visualization I'm abusing view-tree
from rhizome
:
(map (partial zipmap [:edge/from :edge/to :edge/from_node_labe :edge/to_node_label :edge/label])
(mapcat (fn [a] (map (fn [a b] [(:db/id a) (:db/id b) (:node_label a) (:node_label b) (:edge_label b)]) (repeat a) (:predicate/children a)))
(remove (comp empty? :predicate/children)
(tree-seq :predicate/children :predicate/children your-original-data-structure))))
gives:
({:edge/from 17592186325353,
:edge/to 17592186325357,
:edge/from_node_labe "e",
:edge/to_node_label "m",
:edge/label :A2}
{:edge/from 17592186325353,
:edge/to 17592186325348,
:edge/from_node_labe "e",
:edge/to_node_label "a",
:edge/label :A1}
{:edge/from 17592186325357,
:edge/to 17592186325348,
:edge/from_node_labe "m",
:edge/to_node_label "a",
:edge/label :A2}
{:edge/from 17592186325348,
:edge/to 17592186325351,
:edge/from_node_labe "a",
:edge/to_node_label "l",
:edge/label :A1}
{:edge/from 17592186325348,
:edge/to 17592186325351,
:edge/from_node_labe "a",
:edge/to_node_label "l",
:edge/label :A1})
I am not sure if it is the easiest.