Clojure 如果和直到找到结果,则循环,然后退出
我不认为关键是什么?下面的函数按我期望的方式工作。首先,这里是输入数据 从中导出cmp val的数据: [“2”“000-00-0000”“吐司”“法文”“M”“1999年8月26日”“所有护理计划”“医疗”] 缺少密钥(ssn)的数据。 [“000-00-0000”“TOAST”“FRENCH”“关于B部分-投保”] 问题是,如果我把输入的000-00-0000中的一个换成别的东西,我应该 看到了吗,连接到一个对数向量上。我并没有,我也并没有看到它是用“若不是空的话”打印的Clojure 如果和直到找到结果,则循环,然后退出,clojure,Clojure,我不认为关键是什么?下面的函数按我期望的方式工作。首先,这里是输入数据 从中导出cmp val的数据: [“2”“000-00-0000”“吐司”“法文”“M”“1999年8月26日”“所有护理计划”“医疗”] 缺少密钥(ssn)的数据。 [“000-00-0000”“TOAST”“FRENCH”“关于B部分-投保”] 问题是,如果我把输入的000-00-0000中的一个换成别的东西,我应该 看到了吗,连接到一个对数向量上。我并没有,我也并没有看到它是用“若不是空的话”打印的 (defn is-
(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行中的cmp idx位置找到cmp val,我希望这样
分配给rc,循环终止
我如何修复for循环,如果没有,我可以使用什么循环机制来实现这一点
谢谢。- 您不需要
,它专门检查布尔true?
值李>true
- 不要重复呼叫is-a-in-b李>
- 使用
作为fn名称将更为惯用(且可读)李>a-in-b?
- 我建议简化代码,您实际上不需要
let
过滤器
:
(vec (filter #(a-in-b? cmp-val cmp-idx %) csv-data))
此外,这将不仅返回第一个匹配项,而且返回所有匹配项。如果我没看错你的问题,你只需要找到第一个匹配项?然后使用一些:
(some #(a-in-b? cmp-val cmp-idx %) csv-data)
更新
重读你的问题,我觉得你认为<<代码> <代码>是一个循环结构。它不是,它是一个列表理解,生成一个懒惰的seq。要编写一个循环来控制何时迭代,必须使用
loop recur
。但在Clojure中,除了性能,您几乎不需要编写自己的循环。在所有其他情况下,您都可以从clojure.core
中编写高阶函数,我曾经使用for循环来累加,但最后使用reduce解决了我的问题。
(some #(a-in-b? cmp-val cmp-idx %) csv-data)