4

hiccup を使用して、ラベルが続くいくつかのチェックボックスを生成しています。元のコードは次のようになります。

(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")

それがあなたのやりたいことだと私が思うなら、最も簡単な方法ですが、最も一般的ではない方法は、リストへの呼び出しですべてを単純にラップすることです。ただし、より一般的で慣用的なものにするために、次のようにします。

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

for変数(または複数の変数)(この場合はx)をシーケンスの1つの要素に一度に1つずつバインドし、それらすべてを通過するまでループすることによって機能します。このようにして、1、2、3、および4を通過し、letバインド名の内部で(str "check" x)。たとえば、最初の反復では、名前は「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 に答える