2016-07-12 78 views
0

我想創建嵌套地圖mermaid圖這樣的Clojure - 變換嵌套地圖

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

diagram

我覺得應該先轉換嵌套的地圖這種形式。那麼它應該很容易。

[{: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"}] 

編輯:

這是我創造。但我完全不知道如何添加結果地圖的路徑。

(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

你需要用代碼的具體幫助你試過了嗎?你可以發佈嗎? – Bill

+0

@Bill,我需要幫助爲每個項目添加「路徑」。 – Ribelo

+0

通常,將當前級別的路徑聲明(讓)到一個變量中,然後將其添加到正在構建的結構中,然後在遞歸到下一個級別並繼續構建它時將其傳遞給它。在這種情況下,多元函數可能更容易構造,而不是循環。 – Bill

回答

1

據我可以通過人魚文檔看到,繪製圖表它足以產生的「X - > Y」的形式的所有節點對。

,我們可以做到這一點與一些簡單的遞歸函數(我相信,有沒有在圖表中這麼多層次擔心堆棧溢出):

(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))) 

在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") 

所以現在你只需要做一個這樣的圖表:

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

更新

你可以使用同樣的策略在實際地圖變形,​​剛好路過電流路徑map->mermaid

在REPL
(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)))) 

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

我寫了類似於你的東西。問題是密鑰重複。你的結果圖看起來像這樣 https://i.imgur.com/padT6h7.png – Ribelo

+0

所以..那麼得到一個「美人魚」代碼的例子,生成你想要的圖表,我不是很熟悉與它.. – leetwinski

+0

或您的圖片意味着兩張不同的圖表? – leetwinski