我是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})
我尝试使用循环和递归,但我认为在两种情况下均无法递归。
(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))))))))
答案 0 :(得分:1)
仅回答问题(不调查您要实现的内容):您可以 在任何尾部位置重复出现,并且if
的两个分支都在尾部位置。您只需要在处理以下基本情况之前就可以:
(loop [a arg]
(if (base-case? a)
a
(if (my-pred? a)
(recur (frob a))
(recur (whozzle a)))))
您可能会通过分支表示递归来表达这一点,但是(但它的作用相同):
(loop [a arg]
(if (base-case? a)
a
(recur (if (my-pred? a)
(frob a)
(whozzle a)))))
答案 1 :(得分:0)
不直接回答您的问题,但想提供另一种方法来解决问题:
(->> [{:disease :Asthma :start 20 :end 41 :dose 0.25}
{:disease :Asthma :start 31 :end 65 :dose 0.65}
{:disease :BP :start 51 :end 91 :dose 0.75}]
;; EXPAND TO DATE SEQUENCE
;;
(mapcat (fn [{:keys [start end] :as d}]
(let [x (dissoc d :start :end)]
(map (partial assoc x :dt) (range start end)))))
(sort-by :dt)
;; ({:disease :Asthma, :dose 0.25, :dt 20}
;; {:disease :Asthma, :dose 0.25, :dt 21}
;; {:disease :Asthma, :dose 0.25, :dt 22}
;; 'GROUP' SUBSCRIPTIONS BY DATE
;;
(partition-by :dt)
(map #(reduce (fn [s e] (update s :subscriptions conj (dissoc e :dt)))
{:subscriptions #{}
:dt (-> % first :dt)}
%))
(partition-by :subscriptions)
;; (({:subscriptions #{{:disease :Asthma, :dose 0.25}}, :dt 20}
;; ...
;; {:subscriptions #{{:disease :Asthma, :dose 0.25}}, :dt 30})
;; ({:subscriptions
;; #{{:disease :Asthma, :dose 0.25} {:disease :Asthma, :dose 0.65}},
;; :dt 31}
;; ...
;; {:subscriptions
;; #{{:disease :Asthma, :dose 0.25} {:disease :Asthma, :dose 0.65}},
;; :dt 40})
;; GET BACK DATE RANGE FROM PARTITIONS OF SUBSCRIPTIONS
;;
(map #(-> %
first
(dissoc :dt)
(assoc :start (-> % first :dt)
:end (-> % last :dt))))
;; ({:subscriptions #{{:disease :Asthma, :dose 0.25}}, :start 20, :end 30}
;; {:subscriptions
;; #{{:disease :Asthma, :dose 0.25} {:disease :Asthma, :dose 0.65}},
;; :start 31,
;; :end 40}
;; FLATTEN THE LIST BY SUBSCRIPTIONS
;;
(mapcat (fn [{:keys [subscriptions start end]}]
(map #(assoc % :start start :end end) subscriptions)))
(sort-by (juxt :start :disease :dose)))
;; ({:disease :Asthma, :dose 0.25, :start 20, :end 30}
;; {:disease :Asthma, :dose 0.25, :start 31, :end 40}
;; {:disease :Asthma, :dose 0.65, :start 31, :end 40}
;; {:disease :Asthma, :dose 0.65, :start 41, :end 50}
;; {:disease :Asthma, :dose 0.65, :start 51, :end 64}
;; {:disease :BP, :dose 0.75, :start 51, :end 64}
;; {:disease :BP, :dose 0.75, :start 65, :end 90})