Recursion Clojure:Iterate循环在两种条件下均为;如果;

Recursion Clojure:Iterate循环在两种条件下均为;如果;,recursion,vector,clojure,tail-recursion,Recursion,Vector,Clojure,Tail Recursion,我是clojure的新手,一直在尝试解决一个问题,其中一个向量是地图 ({:disease Asthma, :st-dt 2018-2-1, :en-dt 2018-4-1, :dose 0.25} {:disease Asthma, :st-dt 2018-3-1, :en-dt 2018-6-5, :dose 0.65} {:disease BP, :st-dt 2018-5-1, :en-dt 2018-9-1, :dose 0.75}) 是给定的,我必须得到一个不重叠的数据,有点像

我是clojure的新手,一直在尝试解决一个问题,其中一个向量是地图

({:disease Asthma, :st-dt 2018-2-1, :en-dt 2018-4-1, :dose 0.25} 
{:disease Asthma, :st-dt 2018-3-1, :en-dt 2018-6-5, :dose 0.65} 
{:disease BP, :st-dt 2018-5-1, :en-dt 2018-9-1, :dose 0.75})
是给定的,我必须得到一个不重叠的数据,有点像

({:disease Asthma, :st-dt 2018-2-1, :en-dt 2018-2-28, :dose 0.25} 
{:disease Asthma, :st-dt 2018-3-1, :en-dt 2018-4-1, :dose 0.25} 
{:disease Asthma, :st-dt 2018-3-1, :en-dt 2018-4-1, :dose 0.65} 
{:disease Asthma, :st-dt 2018-4-2, :en-dt 2018-4-30, :dose 0.65} 
{:disease Asthma, :st-dt 2018-5-1, :en-dt 2018-6-5, :dose 0.65} 
{:disease BP, :st-dt 2018-5-1, :en-dt 2018-6-5, :dose 0.75}
{:disease BP, :st-dt 2018-6-6, :en-dt 2018-9-1, :dose 0.75})
我尝试过使用循环和重现,但我认为在if的两种情况下都不可能重现

(defn ab [x] (let [temp x olap (f/overlap (f/interval ((first temp ):st-dt) ((first temp ):en-dt)) 
                                          (f/interval ((second temp):st-dt) ((second temp):en-dt) ))]
               (if olap 
                 (into [] (concat [{:med-type ((first temp ):med-type) :st-dt ((first temp ):st-dt)
                                    :en-dt (f/minus ((second temp) :st-dt) (f/days 1)) :dose ((first temp):dose )}
                                   {:med-type ((first temp ):med-type) :st-dt ((second temp ):st-dt)
                                    :en-dt ((first temp) :en-dt) :dose ((first temp):dose )}
                                   {:med-type ((second temp ):med-type) :st-dt ((second temp ):st-dt)
                                    :en-dt ((first temp) :en-dt) :dose ((second temp):dose )}
                                   {:med-type ((second temp ):med-type) :st-dt (f/plus ((first temp ):en-dt) (f/days 1))
                                    :en-dt ((second temp) :en-dt) :dose ((second temp):dose )}] 
                                  (into [] (rest (rest x))))))))

回答这个问题(而不是研究您试图实现什么):您可以在任何尾部位置重复出现,如果
处于尾部位置,则
的两个分支都可以重复出现。您只需在以下情况之前处理基本情况:

(loop [a arg]
  (if (base-case? a)
    a
    (if (my-pred? a)
      (recur (frob a))
      (recur (whozzle a)))))
但是,您可能会通过分支使参数重复出现来表达这一点(但其工作原理相同):


不直接回答您的问题,但希望提供不同的解决方法:

(->[{:疾病:哮喘:开始20:结束41:剂量0.25}
{:疾病:哮喘:开始31:结束65:剂量0.65}
{:疾病:血压:开始51:结束91:剂量0.75}]
;展开到最新序列
;;
(mapcat(fn[{:keys[start-end]:as d}]
(让[x(dissoc d:start:end)]
(映射(部分关联x:dt)(范围开始-结束()())))
(排序方式:dt)
;({:疾病:哮喘,:剂量0.25,:dt20}
疾病:哮喘,剂量0.25,剂量21
疾病:哮喘,剂量0.25,剂量22
按日期“分组”订阅
;;
(按:dt划分)
(map#(reduce(fn[se](更新s:subscriptions conj(dissoc e:dt)))
{:订阅#{}
:dt(->%first:dt)}
%))
(分区依据:订阅)
({:订阅{:疾病:哮喘,:剂量0.25},:dt20}
;;   ...
{:订阅{:疾病:哮喘,剂量0.25},剂量30})
订阅
{{:疾病:哮喘,剂量0.25}{:疾病:哮喘,剂量0.65},
;;:dt 31}
;;    ...
订阅
{{:疾病:哮喘,剂量0.25}{:疾病:哮喘,剂量0.65},
;;:dt 40})
;从订阅分区中获取日期范围
;;
(地图#)(->%
第一
(dissoc:dt)
(关联:开始(->%first:dt)
:end(->%last:dt)))
({:订阅{:疾病:哮喘,:剂量0.25},:开始20,:结束30}
订阅
{{:疾病:哮喘,剂量0.25}{:疾病:哮喘,剂量0.65},
开始,开始,
:结束40}
通过订阅将列表展平
;;
(mapcat(fn[{:keys[subscriptions start end]}]
(映射#(关联%:开始:结束)订阅)))
(排序方式(juxt:start:disease:dose)))
;({:疾病:哮喘,:剂量0.25,:开始20,:结束30}
疾病:哮喘,剂量0.25,开始31,结束40
疾病:哮喘,剂量0.65,开始31,结束40
疾病:哮喘,剂量0.65,开始41,结束50
疾病:哮喘,剂量0.65,开始51,结束64
疾病:血压,剂量0.75,开始51,结束64
{:疾病:血压,:剂量0.75,:开始65,:结束90})
  • 我在这里使用整数作为日期,以便于阅读

谢谢,这很有帮助,实际上我还想在if和recur两种情况下显示一张地图。
(loop [a arg]
  (if (base-case? a)
    a
    (recur (if (my-pred? a)
             (frob a)
             (whozzle a)))))