首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将两个cljure.walking/postwalk调用合并为一个

将两个cljure.walking/postwalk调用合并为一个
EN

Stack Overflow用户
提问于 2015-01-20 14:48:04
回答 1查看 202关注 0票数 1

我有以下数据:

代码语言:javascript
复制
 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样式语法将这些数据转换为嵌套的列表结构。目前,我有以下工作解决方案:

代码语言:javascript
复制
 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)))))

这导致:

代码语言:javascript
复制
[: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中提取所有这些数据)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-21 06:04:56

考虑到您提供的数据,您可以尝试如下所示:

代码语言:javascript
复制
(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))

在后处理过程中,这将将每个映射转换为表示无序列表(甚至是空映射)的向量,将每个键值对转换为表示列表项的向量。(if (= v [:ul]) ...)确保从最终结构中删除空无序列表。

运行(pprint (format-data example))会得到以下结果:

代码语言:javascript
复制
[: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"]]]]]]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28048243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档