将两个clojure.walk/postwark调用合并为一个

将两个clojure.walk/postwark调用合并为一个,clojure,clojurescript,Clojure,Clojurescript,我有以下数据: 28 (def example {"1ce9b863-5681-4660-85e7-fbd0cc184aed" 29 {"58825b50-23bc-4204-8f8d-c9a9d3ac8beb" {}, 30 "4b1763f9-8380-4507-9a8f-5c86878e49a9" {}, 31 "160f34ac-68b9-4c8e-930b-1ab6df895df4" {}}

我有以下数据:

 28 (def example {"1ce9b863-5681-4660-85e7-fbd0cc184aed"
 29               {"58825b50-23bc-4204-8f8d-c9a9d3ac8beb" {},
 30                "4b1763f9-8380-4507-9a8f-5c86878e49a9" {},
 31                "160f34ac-68b9-4c8e-930b-1ab6df895df4" {}},                                                                                
 32               "6378daf6-3b7f-4cf4-8156-a50cf5f7b6ef"
 33               {"669fe949-057f-43c0-af7b-ff39594a183d" {},
 34                "73d2a203-e3c1-4d2f-aaf8-a9f2e870792b" {},
 35                "8c9c57a0-d20d-4474-9afb-c9d17df83a91" {},
 36                "94bf72cb-01cd-4430-b669-b2e954b5639b"
 37                {"ba96a425-a3f0-4ce5-8c19-6ea9add14013" {},
 38                 "1ceff8fe-a0a8-46ad-81a8-d13fb837aaf6" {}}}})
 39 
 40 (def titles (list {:id "58825b50-23bc-4204-8f8d-c9a9d3ac8beb", :title "Low"}
 41                   {:id "4b1763f9-8380-4507-9a8f-5c86878e49a9", :title "Medium"}
 42                   {:id "160f34ac-68b9-4c8e-930b-1ab6df895df4", :title "High"}
 43                   {:id "1ce9b863-5681-4660-85e7-fbd0cc184aed", :title "Priority"}
 44                   {:id "1ceff8fe-a0a8-46ad-81a8-d13fb837aaf6", :title "Drafting"}
 45                   {:id "ba96a425-a3f0-4ce5-8c19-6ea9add14013", :title "Brainstorm"}
 46                   {:id "94bf72cb-01cd-4430-b669-b2e954b5639b", :title "Planning"}
 47                   {:id "8c9c57a0-d20d-4474-9afb-c9d17df83a91", :title "Testing"}
 48                   {:id "73d2a203-e3c1-4d2f-aaf8-a9f2e870792b", :title "Implementation"}
 49                   {:id "669fe949-057f-43c0-af7b-ff39594a183d", :title "Completed"}
 50                   {:id "6378daf6-3b7f-4cf4-8156-a50cf5f7b6ef", :title "Status"}))
我试图使用sablono/hiccup风格的语法将这些数据转换成嵌套的列表结构。目前我有以下工作解决方案:

 52 (defn id->title [x]
 53   (let [tuples (map (fn [x] [(:id x) (:title x)]) titles)]
 54     (first (for [[k t] tuples :when (= k x)] t))))               

 57 (->> example
 58      (clojure.walk/postwalk
 59        (fn [x] (if-not (string? x)
 60                  (vec x) x)))
 61      (clojure.walk/postwalk
 62        (fn [x] (if (vector? x)
 63                  (if (vector? (first x))
 64                    (vec (cons :ul x))
 65                    (vec (cons :li x)))
 66                  (id->title x)))))
这导致:

[:ul  
 [:li "Priority"
  [:ul 
    [:li "Low" [:li]] 
    [:li "Medium" [:li]] 
    [:li "High" [:li]]]]
 [:li "Status"
  [:ul
   [:li "Completed" [:li]]
   [:li "Implementation" [:li]]
   [:li "Testing" [:li]]
   [:li "Planning"
    [:ul 
      [:li "Brainstorm" [:li]] 
      [:li "Drafting" [:li]]]]]]]

我怎样才能简化这个过程,使用一次步行?我也在考虑用地图替换
标题
,以便高效查找(我从Neo4j中提取所有这些数据)。

根据您提供的数据,您可以尝试以下方法:

(defn id->title [x]
  (->> titles (filter #(= (:id %) x)) first :title))

(defn format-data [structure]
  (clojure.walk/postwalk
    (fn [x]
      (if (map? x)
        (into [:ul] (map (fn [[k v]]
                           (if (= v [:ul])
                             [:li (id->title k)]
                             [:li (id->title k) v]))
                         (seq x)))
        x))
  structure))
在postwalk期间,这会将每个映射转换为表示无序列表的向量(甚至是空映射),并将每个键值对转换为表示列表项的向量。
(if(=v[:ul])…
确保从最终结构中删除空的无序列表

运行
(pprint(格式数据示例))
将给出以下结果:

[:ul
 [:li "Priority" [:ul [:li "Low"] [:li "Medium"] [:li "High"]]]
 [:li
  "Status"
  [:ul
   [:li "Completed"]
   [:li "Implementation"]
   [:li "Testing"]
   [:li "Planning" [:ul [:li "Brainstorm"] [:li "Drafting"]]]]]]

乍一看,这正是我需要的。在我接受答案之前,我将在今天晚些时候进行测试。这是否适用于相同结构的无限嵌套贴图?这仅适用于有限深度的嵌套贴图
postwalk
执行深度优先遍历,因此如果有无限嵌套的贴图,它将永远搜索,试图找到所有的叶子。在这种情况下,您必须采取不同的方法。