0

私はキープレスとは思わない?以下の関数は、期待どおりに機能しています。まず、ここに入力データがあります。

cmp-val の元となったデータ: ["2" "000-00-0000" "TOAST" "FRENCH" "" "M" "26-Aug-99" "" "ALL CARE PLAN" "MEDICAL"]キー (ssn) がありません。["000-00-0000" "TOAST" "FRENCH" "RE-PART B - 被保険者"]

問題は、入力の 000-00-0000 の 1 つを別のものにすると、それが対数ベクトルに conj されていることがわかるはずです。私はしませんし、if-not empty? で印刷されていません。

(defn is-a-in-b
    "This is a helper function that takes a value, a column index, and a 
     returned clojure-csv row (vector), and checks to see if that value
     is present. Returns value or nil if not present."

    [cmp-val col-idx csv-row]

    (let [csv-row-val (nth csv-row col-idx nil)]
        (if (= cmp-val csv-row-val)
            cmp-val
            nil)))

(defn key-pres?
    "Accepts a value, like an index, and output from clojure-csv, and looks
     to see if the value is in the sequence at the index. Given clojure-csv
     returns a vector of vectors, will loop around until and if the value
     is found."

    [cmp-val cmp-idx csv-data]

    (let [ret-rc 
        (for [csv-row csv-data
                :let [rc (is-a-in-b cmp-val cmp-idx csv-row)]
                :when (true? (is-a-in-b cmp-val cmp-idx csv-row))]
            rc)]
        (vec ret-rc)))

(defn test-key-inclusion
    "Accepts csv-data file and an index, a second csv-data param and an index,
     and searches the second csv-data instances' rows (at index) to see if
     the first file's data is located in the second csv-data instance."

    [csv-data1 pkey-idx1 csv-data2 pkey-idx2]

    (reduce
        (fn [out-log csv-row1]
            (let [cmp-val (nth csv-row1 pkey-idx1 nil)]
                (doseq [csv-row2 csv-data2]
                  (let [temp-rc (key-pres? cmp-val pkey-idx2 csv-row2)]
                      (if-not (empty? temp-rc) 
                          (println cmp-val, " ", (nth csv-row2 pkey-idx2 nil), " ", temp-rc))
                      (if (nil? temp-rc)
                        (conj out-log cmp-val))))))
         []
         csv-data1))

私が関数に実行させたいのは、clojure-csv (ベクトルのベクトル) によって返されたデータをトラバースすることです。cmp-val が csv-row の cmp-idx の場所にある場合は、それを rc に割り当てて、ループを終了させたいと思います。

for ループを修正するにはどうすればよいですか? そうでない場合は、これを達成するためにどのループ メカニズムを使用できますか?

ありがとうございました。

4

1 に答える 1

1
  • は必要ありません。具体的にはブール値true?をチェックします。true
  • is-a-in-b への呼び出しを繰り返さないでください。
  • a-in-b?fn 名として使用する方が慣用的 (かつ読みやすい) でしょう。
  • コードを単純化することをお勧めします。実際には必要ありませんlet

コード:

(vec (for [csv-row csv-data
           :let [rc (a-in-b? cmp-val cmp-idx csv-row)]
           :when rc)]
        rc))

しかし、これはコードスタイルに関する一般的なコメントにすぎません...ここで実装しているのは単純なものですfilter:

(vec (filter #(a-in-b? cmp-val cmp-idx %) csv-data))

さらに、これは最初の一致だけでなく、すべての一致を返します。あなたの質問を正しく読んだら、最初の一致を見つけるだけでいいのですか? 次に使用しますsome

(some #(a-in-b? cmp-val cmp-idx %) csv-data)

アップデート

forあなたの質問を読み直すと、あなたはループ構造であると考えているように感じます。そうではありません -- これはリスト内包表記であり、怠惰な seq を生成します。反復するタイミングを制御するループを作成するには、 を使用する必要がありますloop-recur。しかし、Clojure では、パフォーマンスを除いて、独自のループを記述する必要はほとんどありません。それ以外の場合はすべて、 から高階関数を構成しclojure.coreます。

于 2012-04-11T21:40:31.300 に答える