Clojure问题
我在clojure中编写了以下函数:在第一个循环中,它迭代一个映射列表并创建一个映射.然后第二个循环迭代一个列表,匹配先前创建的映射数据和一个向量并返回一个新映射.但是,使用相同数据的不同运行会产生不同的结果.见下文.
(defn resolve-case-per-period
"Constructs a map by matching data existing in input parameter vectors"
[dd case-details periods]
(let [cases ((fn [in]
(loop [case-details in, result-map {}]
(if (= (count case-details) 0)
result-map
(recur (rest case-details)
(assoc result-map
(:priority (first case-details))
(:caseid (first case-details)))))))
case-details)
periods periods]
(info "Mapping cases to periods step 1 completed " cases)
(loop [periods periods, result-map {}]
(if (= (count periods) 0)
result-map
(recur (rest periods)
(conj result-map
{ (str (:period (first periods)))
(get cases (:priority (first periods)))}))))))
Run Code Online (Sandbox Code Playgroud)
返回的输出是如下地图:
{31-10-10 20 10020101030122036M, 31-10-10 10 10020101030122036M, 31-10-10 21 10020101030122036M, 30-10-10 21 10020101030200157M, 31-10-10 00 10020101030122036M, 31-10-10 11 10020101030122036M, 31-10-10 22 10020101031112152M, 30-10-10 22 10020101030122036M, 31-10-10 01 10020101030122036M, 31-10-10 12 10020101030122036M, 30-10-10 23 10020101030122036M, 31-10-10 02 10020101030122036M, 31-10-10 13 10020101030122036M, 31-10-10 03 10020101030122036M, 31-10-10 14 10020101030122036M, 31-10-10 04 10020101030122036M, 31-10-10 15 10020101030122036M, 31-10-10 05 10020101030122036M, 31-10-10 16 10020101030122036M, 31-10-10 06 10020101030122036M, 31-10-10 17 10020101030122036M, 31-10-10 07 10020101030122036M, 31-10-10 18 10020101030122036M, 31-10-10 08 10020101030122036M, 31-10-10 19 10020101030122036M, 31-10-10 09 10020101030122036M}
Run Code Online (Sandbox Code Playgroud)
执行具有相同参数的函数有时会产生
{31-10-10 20 nil, 31-10-10 10 nil, 31-10-10 21 nil, 30-10-10 21 nil, 31-10-10 00 nil, 31-10-10 11 nil, 31-10-10 22 nil, 30-10-10 22 nil, 31-10-10 01 nil, 31-10-10 12 nil, 30-10-10 23 nil, 31-10-10 02 nil, 31-10-10 13 nil, 31-10-10 03 nil, 31-10-10 14 nil, 31-10-10 04 nil, 31-10-10 15 nil, 31-10-10 05 nil, 31-10-10 16 nil, 31-10-10 06 nil, 31-10-10 17 nil, 31-10-10 07 nil, 31-10-10 18 nil, 31-10-10 08 nil, 31-10-10 19 nil, 31-10-10 09 nil}
Run Code Online (Sandbox Code Playgroud)
这个函数中的所有东西都是确定性的和纯粹的(除了info调用,这应该不重要),所以每次都应该返回相同的东西.您没有提供任何样本输入,因此我无法反驳这一假设.
代码很难阅读,没有上下文我真的不明白你在做什么.但是我在几个重构过程中经历了你的代码,试图让它更清楚地发生了什么.希望这可以帮助正在阅读的其他人,甚至可以让你在问题所在的地方更清楚.
删除所有疯狂的格式和无意义的变量复制,并使用seq而不是测试count = 0
(defn resolve-case-per-period
"Constructs a map by matching data existing in input parameter vectors"
[dd case-details periods]
(let [cases (loop [case-details case-details, result-map {}]
(if (seq case-details)
(recur (rest case-details)
(assoc result-map
(:priority (first case-details))
(:caseid (first case-details))))
result-map))]
(info "Mapping cases to periods step 1 completed " cases)
(loop [periods periods, result-map {}]
(if (seq periods)
(recur (rest periods)
(assoc result-map
(str (:period (first periods)))
(get cases (:priority (first periods)))))
(do (info "Mapping cases to periods step 2 completed " result-map)
result-map)))))
Run Code Online (Sandbox Code Playgroud)
解构和if-let而不是原始关键字查找,ifs和seqs:
(defn resolve-case-per-period
"Constructs a map by matching data existing in input parameter vectors"
[dd case-details periods]
(let [cases (loop [case-details case-details, result-map {}]
(if-let [[{:keys [priority case-id]} & more] (seq case-details)]
(recur more
(assoc result-map priority caseid))
result-map))]
(info "Mapping cases to periods step 1 completed " cases)
(loop [periods periods, result-map {}]
(if-let [[{:keys [period priority]} & more] (seq periods)]
(recur more
(assoc result-map
(str period)
(get cases priority)))
(do (info "Mapping cases to periods step 2 completed " result-map)
result-map)))))
Run Code Online (Sandbox Code Playgroud)
在这一点上,我们最终清楚地看到我们只是迭代一个序列并构建一个结果值,所以我们可以删除所有的第一个/其余的废话并且只是reduce用来遍历我们的序列:
(defn resolve-case-per-period
"Constructs a map by matching data existing in input parameter vectors"
[dd case-details periods]
(let [cases (reduce (fn [result-map {:keys [priority case-id]}]
(assoc result-map priority caseid))
{}, case-details)]
(info "Mapping cases to periods step 1 completed " cases)
(reduce (fn [result-map {:keys [period priority]}]
(assoc result-map
(str period)
(get cases priority)))
{}, periods)))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
116 次 |
| 最近记录: |