0

我不认为按键?下面的功能按我期望的方式工作。首先,这是输入数据。

cmp-val 派生的数据:[“2”“000-00-0000”“TOAST”“FRENCH”“”“M”“26-Aug-99”“”“ALL CARE PLAN”“MEDICAL”]缺少密钥 (ssn)。[“000-00-0000”“吐司”“法式”“B 部分 - 已投保”]

问题是,如果我将输入的 000-00-0000 之一设为其他内容,我应该看到 conj'd 到对数向量上。我没有,而且我没有看到它印有 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(向量的向量)返回的数据。如果可以在 csv-row 中的 cmp-idx 位置找到 cmp-val,我希望将其分配给 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这是一个循环构造。它不是——它是一个列表推导,产生一个惰性序列。要编写一个循环来控制何时进行迭代,您必须使用loop-recur. 但是在 Clojure 中,您几乎不需要编写自己的循环,除了性能。在所有其他情况下,您可以从clojure.core.

于 2012-04-11T21:40:31.300 回答