将两个 clojure.walk/postwalk 调用合并为一个
Combining Two clojure.walk/postwalk Calls Into One
我有以下数据:
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]]]]]]]
我怎样才能将其简化为一次步行?我也在考虑用地图替换 titles
以进行高效查找(我正在从 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 (format-data example))
给出以下结果:
[: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"]]]]]]
我有以下数据:
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]]]]]]]
我怎样才能将其简化为一次步行?我也在考虑用地图替换 titles
以进行高效查找(我正在从 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 (format-data example))
给出以下结果:
[: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"]]]]]]