4

我正在使用打嗝来生成一些复选框,然后是标签。原始代码如下所示:

(check-box "check1")
(label "check1" "Check1") 
(check-box "check2")
(label "check2" "Check2")
(check-box "check1")
(label "check3" "Check3")
(check-box "check4")
(label "check4" "Check4")

经过大量的修修补补,我得出以下结论:

(map
    (fn [x]
        (map
            #(get (vector
                (check-box x)
                (label x (capitalize x)))%)
            [0 1]))
    ["check1" "check2" "check3" "check4"])

哪个有效,但我觉得我并没有以非常类似 lisp/优化/正确/等的方式进行操作。方式 - 特别是返回一个向量只是为了用 get 舀出这些值。有一个更好的方法吗?

4

3 回答 3

11

也许解构是你需要的?

(defn multi-return-fn []
  [:1 :2 :3])

(let [[x y z] (multi-return-fn)]
    (println x)
    (println y)
    (println z))

解构也适用于 fn 参数、循环、for 循环等。

于 2012-07-09T16:51:04.050 回答
5

正如其他人所指出的,您的问题不是很清楚,但是在正常的 Hiccup 应用程序的上下文中,假设您可能想要以下内容是合理的:

(apply concat
       (for [boxnum (range 1 5)
             :let [lower-name (str "check" boxnum)
                   upper-name (str "Check" boxnum)]]
         [(check-box lower-name)
          (label lower-name upper-name)]))

您可以通过多种其他方式编写它;这个错误在于冗长而清晰,而不是简洁。

于 2012-07-09T18:25:00.230 回答
1

在 amalloy 评论后编辑

我不知道打嗝,我不完全理解你想要做什么。具体来说,我不明白get你必须按照自己的意愿去做的那一行。但是,您似乎在说您想要来自以下代码块的返回值列表:

(check-box "check1")
(label "check1" "Check1") 
(check-box "check2")
(label "check2" "Check2")
(check-box "check1")
(label "check3" "Check3")
(check-box "check4")
(label "check4" "Check4")

如果我是对的,那就是你想要做的,那么最简单的方法——但最不通用的方法——就是简单地将它全部包装在对 list 的调用中。但是,为了使其更通用和惯用,我会这样做:

(apply concat
  (for [x [1 2 3 4]
        :let [name (str "check" x)]]
    [(check-box name)
     (label name (capitalize name))]))

for通过将一个(或多个)变量(在本例中为 x)绑定到序列中的一个元素,一次一个,然后循环,直到它通过所有这些元素。这样,它经过 1、2、3 和 4,然后在letbinds name to内(str "check" x)。例如,在第一次迭代中,name 将被绑定为“check1”。剩下的就是简单地用适当的参数调用check-boxandlabel函数。

如果你想进一步概括这一点——例如,你可能不知道你想要多少个复选框和标签——你可以像这样轻松地做到这一点:

(defn make-n-checkboxes-and-labels
  [n]
  (apply concat
    (for [x (range 1 (inc n))
          :let [name (str "check" x)]]
      [(check-box name)
       (label name (capitalize name))])))

在这种情况下,它现在已被泛化为一个函数,您可以执行与以前完全相同的操作,但现在通过执行以下操作:

(make-n-checkboxes-and-labels 4)

再说一次,我没有对打嗝做任何研究,所以我可能不知道你到底想做什么。此外,Timothy 可能建议(隐含地,不明确地)用关键字替换字符串。我会重申这个建议,因为关键字应该更快更好看(在这种情况下,它们也可能更惯用)。如果你想用关键字替换你的字符串,它应该是一个简单的环绕(keyword)字符串的问题,如下所示:

(keyword (str "check" 1))
=> :check1

祝你好运!

于 2012-07-09T18:02:43.213 回答