1

我有一组 URL,其中一些 URL 具有间接引用(作为向量)。任何没有间接引用的 URL 都只有nil. 我从以下测试地图开始:

{"URL 1" nil,
 "URL 2" ["indirect 1" "indirect 2"]}

我正在使用打嗝来构建 HTML 报告,所以我想要这个输出:

[:div "Imports: "
 [:ul
  [:li "URL 1"]
  [:li "URL 2"]
    [:ul
     [:li "indirect 1"]
     [:li "indirect 2"]
     [:li "indirect 3"]]]]

当 URL 没有间接引用时,我遇到了一些返回 nil 的问题。我当前的代码如下所示:

(defn list-imports
  [imports]
  (if-not (nil? imports)
    [:div "Imports: "
     [:ul
      (for [direct (keys imports)]
        [[:li direct]
         (if-let [indirects (get imports direct)]
           [:ul
             (for [indirect indirects]
               [:li indirect])]
           [:span])])]]
    [:div "Imports: none" [:br] [:br]]))

问题是,它正在返回这个......

[:div
 "Imports: "
 [:ul
  ([[:li "URL 1"] [:span]]
   [[:li "URL 2"] [:ul ([:li "indirect 1"] [:li "indirect 2"])]])]]

我必须添加一个[:span]标签,以作为间接导入时的情况nil,我真的不想在那里......但否则,它就会放在nil那里。

另一个问题是它最终包含在()一个额外的向量中,因为我在 for 语句中做了很多事情。当我尝试用打嗝转换它时,我得到[:li "URL 1"] is not a valid element name.

4

1 回答 1

1

这可能是构建打嗝标签的一个棘手方面。有时它有助于将问题分解成更小的部分。

(defn list-indirects
  [indirects]
  (when (seq indirects)
    [(into [:ul] (mapv (fn [i] [:li i]) indirects))]))

(defn list-imports
  [imports]
  (if (some? imports)
    [:div "Imports: "
     (into [:ul]
       (for [[url indirects] imports]
         (into [:li url] (list-indirects indirects))))]
    [:div "Imports: none" [:br] [:br]]))

这些功能应该为您提供所需的输出。

(list-imports {"URL 1" nil
               "URL 2" ["indirect 1" "indirect 2"]})
=>
[:div "Imports: "
 [:ul
  [:li "URL 1"]
  [:li "URL 2"
   [:ul
    [:li "indirect 1"]
    [:li "indirect 2"]]]]]

此输出与您的预期输出略有不同,但我认为它更接近您实际想要的,即您的示例中的标记[:li "URL 2"]包含:ul“间接”的有效 HTML。

如果这些项目的顺序很重要,需要注意的另一件事是,地图可能不会按照您期望的方式排序,尤其是当您拥有超过一定数量的键时。当您遍历地图构建打嗝时,它可能"URL 2"在之前 "URL 1"出现。您可以通过使用元组向量或排序映射来解决此问题。

于 2017-11-02T13:07:20.987 回答