Clojure 列表理解和试剂的唯一值

Clojure list comprehension and unique values for reagent

假设我们有这个网格,其值可以是 0 或 1:

(def grid [[1 0 1]
           [1 0 0]
           [1 0 1]])

现在我想使用列表理解将 grid 转换为 html 类似打嗝的格式:

(defn cell-component [is-it-1 key]
  ^{:key key} [:td (if (= is-it-1 1) {:class "is-it-1"})])


(defn grid-html []
  ([:table
   [:tbody
   (for [row grid]
      ^{:key row} [:tr 
                      (for [cell row]
                      (cell-component cell how-i-can-generate-a-index?))])]]))

table 生成正确,但我不知道如何为我的 td 制作 unique indexhow-i-can-generate-a-index? 应该是多少?

您只需拨打 gensym:

(cell-component cell (gensym))

这是一种通用的方法。然而,通常最好在您的数据中找到一些已经提供独特差异化的属性。

如果您希望看到数字从 0 开始计数,那么您可以编写自己的序列生成器:

(def uniq-key (atom -1))
(defn gen-key []
  (swap! uniq-key inc)) 

使用上面的方法,第一次调用 (gen-key) 返回 0,第二次返回 1,依此类推

在您的例子中,每个单元格都由其在行中的索引唯一标识。此外,在父结构中而不是在组件中指定子键会更自然:

(defn cell-component [is-it-1]
  [:td (if (= is-it-1 1) {:class "is-it-1"})])

(for [[i cell] (map-indexed vector row)]
  ^{:key i} [cell-component cell])

请注意,您应该类似地将基于索引的键分配给行 - 如果您在 table 中有重复的行,^{:key row} 将不起作用。

我建议定义接受 propschildren 作为参数的试剂成分。

(defn my-li
  [:keys [a-string]]
  [:li
   a-string])

(defn my-list
  [{:keys [color]} & children]
  [:ul
   {:style {:background-color color}}
   (map-indexed #(with-meta %2 {:key %1}) children)])

(defn thelist []
  [my-list
   {:color "#ccc"}
   [my-li "one"]
   [my-li "two"]])

改编自https://github.com/reagent-project/reagent/issues/68