Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure不一致会在函数执行期间导致Clojure_Clojure - Fatal编程技术网

Clojure不一致会在函数执行期间导致Clojure

Clojure不一致会在函数执行期间导致Clojure,clojure,Clojure,Clojure问题 我用clojure编写了以下函数: 在第一个循环中,它迭代一个映射列表并创建一个映射。 然后第二个循环迭代一个列表,匹配先前创建的映射中的数据 和一个向量,并返回一个新的映射。但是,使用相同数据的不同运行会产生 净结果不同。见下文 (defn resolve-case-per-period "Constructs a map by matching data existing in input parameter vectors" [dd case-details p

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)))}))))))
返回的输出是如下所示的映射:

{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}
使用相同的参数执行函数有时会产生

{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}

如果我们不知道您的数据(函数输入)是什么样子,则很难回答您的问题,但有几点:

  • dd
    从未在函数中使用,因此您可以将其删除
  • Clojure的习惯用法是使用相当短的函数,因此我建议将在
    let
    中执行的部分分解为另一个函数。这也将使repl的测试和实验更加容易
  • 在let中将
    periods
    重新映射到
    periods
    没有任何效果,所以请去掉它
  • 你在
    let
    中隐藏了大量的局部变量(
    case details
    ,在
    loop
    中隐藏了
    periods
    ),这可能会造成混乱,我建议不要这样做
  • 生成的映射中的键是字符串,我假定其形式为“31-10-10-20”。用引号更容易看出这一点

  • 老实说,我不明白这个Clojure函数如何负责提供不同的输出,您是否绝对确定输入是相同的?作为第一种情况下的观察,你会得到值的大小数,所以我猜在第二种情况下,一些无法处理大小数的东西与数据接触。但是我看不出在您提供的函数中会发生这种情况。

    此函数中的所有内容都是确定的和纯粹的(除了
    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)))))
    
    第二 分解结构和if let而不是基本关键字查找、if和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)))))
    
    第三 在这一点上,我们终于清楚了,我们只是在一个序列上进行迭代,并在执行过程中建立一个结果值,因此我们可以放弃所有的first/rest废话,只需使用
    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)))
    

    我真的很喜欢您展示如何多次传递代码,每次都进行改进的方式。谢谢你抽出时间。我建议从原始函数的参数列表中删除
    dd
    。AFAICS它没有在任何地方使用。谢谢你的详尽回答。谢谢你的详尽回答。第一个数据结构case details是一个包含映射数据结构的列表,如下所示{:caseid1002010101029093512m,:exectime 29-oct-2010 09:35:17,:priority 30856568000M,:studymodeid 11M}。第二个参数periods是另一个列表,其中包含以下实例{:period 29-10-1021,:priority 30851039000M}。我想做的是用从第二个列表中提取的key:period和从第一个列表中提取的value:caseid构建一个映射。我仍然有同样的问题。两次连续运行产生以下结果:lein run 20-10-2010 1021 141954 619 INFO quartzTest.dao[main]检索案例列表当天的4个案例1021 141954 729 INFO quartzTest.dao[main]检索周期和相应的最新执行时间:25 1021 141954 812 INFO quartzTest.utils[main]完成每个周期的案例解析{20-10-10 20 nil,…}和lein运行21-10-2010 1021 142111 154 INFO quartzTest.dao[main]检索案例列表当天的4个案例1021 142111 317 INFO quartzTest.utils[main]完成每个周期的案例解析{21-10-10 10 1002010101020111632M…}如果您在答案中遇到一些棘手的问题,请不要讨论,Clojure不同于更多的过程语言,因此它可能更难开始。但是这些差异有很好的原因,我相信如果你坚持一点,你会看到好处。