簡體   English   中英

Clojure-轉換嵌套地圖

[英]Clojure - transform nested map

我想從這樣的嵌套地圖創建一個美人魚

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

據我從美人魚文檔可以看到的那樣,繪制圖形就足以生成“ 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)))

代表:

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM