如何避免 Clojure 中嵌套的 `for` 函数?

How do I avoid nested `for` functions in Clojure?

在我不断努力复制 Clojure 中的命令式编程的过程中,我似乎仍在嵌套 for 个函数。

例如,如果我想开始:

[[{:a 1 :b 2 :c 3} {:a 1 :b 2 :c 3}] [{:a 2 :b 2 :c 3} {:a 2 :b 2 :c 3}]]

并得到:

[[:table [:tr [:td {:class "a-1" "b-2" "c-3"}] [:td {:class "a-2" "b-2" "c-3"}]]

如果没有我熟悉的来自其他语言的 classic 嵌套 for 语句,我将如何做到这一点?

我意识到我应该在这里粘贴我的尝试,但它太糟糕了。

更新:请参阅下面的一点,我在 :class 值中使用了不正确的打嗝。

我的建议是查看数据结构(您已经拥有)并尝试根据给定的数据分解问题。

你有一个类似于行和单元格的结构,所以这是一种方法。您格式化行,这是格式化单个单元格的结果,然后每个单元格需要有 CSS classes 作为散列映射传递。

考虑到这一点:

(defn cell-classes [cell]
  (->> (map (fn [[k v]] (str (name k) "-" v)) cell)
       (interpose " ")
       (reduce str)))

(defn format-cell [cell]
  (let [classes (cell-classes cell)]
    [:td {:class classes}]))

(defn format-row [cells]
  (->> (map format-cell cells)
       (into [:tr])))

(defn format-rows [rows]
  (->> (map format-row rows)
       (into [:table])))

如果我们使用您的示例数据对其进行测试:

(clojure.pprint/pprint (format-rows [[{:a 1 :b 2 :c 3} {:a 1 :b 2 :c 3}] [{:a 2 :b 2 :c 3} {:a 2 :b 2 :c 3}]]))

它打印

[:table
 [:tr [:td {:class "a-1 b-2 c-3"}] [:td {:class "a-1 b-2 c-3"}]]
 [:tr [:td {:class "a-2 b-2 c-3"}] [:td {:class "a-2 b-2 c-3"}]]]

PS:你想要的输出中有一个小问题,那就是 {:class "a-1" "b-2" "c-3"} 不会是打嗝的理想输出,这就是为什么我加入 class 名称与 space 在 cell-classes.