2016-07-12 11 views
0

Ich mag eine mermaid Graph von verschachtelter Karte erstellen, wie dieseClojure - Transformation verschachtelte Karte

{"a" {"b" {"c" nil 
      "d" nil}} 
"e" {"c" nil 
     "d" {"h" {"i" nil 
       "j" nil}}}} 

diagram

ich denke, es sollte zunächst verschachtelte Karte auf diese Form konvertieren. Dann sollte es einfach sein.

[{:out-path "a" :out-name "a" 
    :in-path "a-b" :in-name "b"} 
{:out-path "a-b" :out-name "b" 
    :in-path "a-b-c" :in-name "c"} 
{:out-path "a-b" :out-name "b" 
    :in-path "a-b-d" :in-name "d"} 
{:out-path "e" :out-name "e" 
    :in-path "e-f" :in-name "f"} 
{:out-path "e" :out-name "e" 
    :in-path "e-c" :in-name "c"} 
{:out-path "e" :out-name "e" 
    :in-path "e-d" :in-name "d"} 
{:out-path "e-d" :out-name "d" 
    :in-path "e-d-h" :in-name "h"} 
{:out-path "e-d-h" :out-name "h" 
    :in-path "e-d-h-i" :in-name "i"} 
{:out-path "e-d-h" :out-name "h" 
    :in-path "e-d-h-j" :in-name "j"}] 

EDIT:

Dies ist, was ich geschaffen habe. Aber ich habe absolut keine Idee, wie man den Pfad zur Ergebniskarte hinzufügt.

(defn myfunc [m] 
    (loop [in m out []] 
    (let [[[k v] & ts] (seq in)] 
     (if (keyword? k) 
     (cond 
      (map? v) 
      (recur (concat v ts) 
       (reduce (fn [o k2] 
          (conj o {:out-name (name k) 
            :in-name (name k2)})) 
         out (keys v))) 
      (nil? v) 
      (recur (concat v ts) out)) 
     out)))) 
+1

Sie benötigen spezielle Hilfe mit Code dass du es versucht hast? Könnten Sie das posten? – Bill

+0

@Bill, ich brauche Hilfe den "Pfad" für jeden Artikel hinzufügen. – Ribelo

+0

Normalerweise würden Sie den Pfad der aktuellen Ebene in eine Variable deklarieren (lassen), dann fügen Sie diese der Struktur, die Sie erstellen, hinzu und übergeben sie dann, wenn Sie zur nächsten Ebene zurückkehren und sie weiter erstellen. Eine Multiaritätsfunktion könnte in diesem Fall einfacher zu strukturieren sein als eine Schleife. – Bill

Antwort

1

so weit wie i von Meerjungfrau docs sehen kann, um das Diagramm zu zeichnen ist es genug, um alle Knoten in der Form von „x -> y“ zu erzeugen Paaren.

könnten wir das tun einige mit einer einfachen rekursiven Funktion (ich glaube es gibt nicht so viele Ebenen in einem Diagramm über Stapelüberlauf sorgen):

(defn map->mermaid [items-map] 
    (if (seq items-map) 
    (mapcat (fn [[k v]] (concat 
          (map (partial str k "-->") (keys v)) 
          (map->mermaid v))) 
     items-map))) 

in repl:

user> 
(map->mermaid {"a" {"b" {"c" nil 
         "d" nil}} 
       "e" {"c" nil 
        "d" {"h" {"i" nil 
           "j" nil}}}}) 

;; ("a-->b" "b-->c" "b-->d" "e-->c" "e-->d" "d-->h" "h-->i" "h-->j") 

so jetzt müssen Sie nur noch eine grafische Darstellung der es so machen:

(defn create-graph [items-map] 
    (str "graph LR" 
     \newline 
     (clojure.string/join \newline (map->mermaid items-map)) 
     \newline)) 

Update

Sie die gleiche Strategie für die eigentliche Karte Transformation vorbei den aktuellen Pfad zu map->mermaid, nur verwenden:

(defn make-result-node [path name child-name] 
    {:out-path path 
    :out-name name 
    :in-path (str path "-" child-name) 
    :in-name child-name}) 

(defn map->mermaid 
    ([items-map] (map->mermaid "" items-map)) 
    ([path items-map] 
    (if (seq items-map) 
    (mapcat (fn [[k v]] 
       (let [new-path (if (seq path) (str path "-" k) k)] 
       (concat (map (partial make-result-node new-path k) 
           (keys v)) 
         (map->mermaid new-path v)))) 
      items-map)))) 

in repl:

user> 
(map->mermaid {"a" {"b" {"c" nil 
         "d" nil}} 
       "e" {"c" nil 
        "d" {"h" {"i" nil 
           "j" nil}}}}) 

;; ({:out-path "a", :out-name "a", :in-path "a-b", :in-name "b"} 
;; {:out-path "a-b", :out-name "b", :in-path "a-b-c", :in-name "c"} 
;; {:out-path "a-b", :out-name "b", :in-path "a-b-d", :in-name "d"} 
;; {:out-path "e", :out-name "e", :in-path "e-c", :in-name "c"} 
;; {:out-path "e", :out-name "e", :in-path "e-d", :in-name "d"} 
;; {:out-path "e-d", :out-name "d", :in-path "e-d-h", :in-name "h"} 
;; {:out-path "e-d-h", :out-name "h", :in-path "e-d-h-i", :in-name "i"} 
;; {:out-path "e-d-h", :out-name "h", :in-path "e-d-h-j", :in-name "j"}) 
+0

Ich schrieb dir etwas ähnliches. Das Problem ist, wenn die Schlüssel dupliziert werden. Ihr Ergebnisdiagramm sieht wie folgt aus: https://i.imgur.com/padT6h7.png – Ribelo

+0

also .. dann wäre es nett, ein Beispiel für "Meerjungfrau" -Code zu bekommen, das Ihr gewünschtes Diagramm erzeugt, ich bin nicht wirklich vertraut mit ihm .. – leetwinski

+0

oder dieses Bild von dir bedeutet zwei verschiedene Diagrammblätter? – leetwinski

Verwandte Themen