Clojure中的日期周期 [英] Date periods in clojure
问题描述
我有一个这样的数据结构:
I have a data structure like this:
[{ :2007-08-05 [ { :meat-weight-gain 100} {:meat-weight-loss 80} {:meat-balance 20}]},
{ :2007-08-06 [ { :meat-weight-gain 10} {:meat-weight-loss 60} {:meat-balance -30}]},
{ :2007-08-07 [ { :meat-weight-gain 40} {:meat-weight-loss 80} {:meat-balance -70}]}
{ :2007-08-08 [ { :meat-weight-gain 100} {:meat-weight-loss 0} {:meat-balance 30}]}]
我如何遍历它并返回肉类平衡为负数的数据周期?样本数据如下所示:
How can i iterate through it and return the data period of when the meat balance was negative? A sample data would be something like this:
[ {:end-period-balance -70, :period-start 2007-08-06, :period-end 2007-08-07 } ]
除此之外,我可以吗改善我的数据结构还是可以的?如果是,怎么办?非常感谢。
Other than that, can I improve my data structure or it is already ok? If yes, how? Thank you very much.
推荐答案
我建议您将数据形状更改为元组列表,每个元组都包含日期和地图余额数据。就像这样:
i would advice you to change your data shape to a list of tuples, each containing date and map of balance data. Just like this:
(def data [[:2007-08-05 { :meat-weight-gain 100 :meat-weight-loss 80 :meat-balance 20}],
[:2007-08-06 { :meat-weight-gain 10 :meat-weight-loss 60 :meat-balance -30}],
[:2007-08-07 { :meat-weight-gain 40 :meat-weight-loss 80 :meat-balance -70}]
[:2007-08-08 { :meat-weight-gain 100 :meat-weight-loss 0 :meat-balance 30}]
[:2007-08-09 { :meat-weight-gain 19 :meat-weight-loss -20 :meat-balance -10}]])
然后按体重增加/减少对时期进行分类(使用分区
)并收集所需的信息:
then it would be easy to classify the periods by weight gain/loss (using partition-by
) and collect needed info:
user> (let [parts (partition-by #(-> % second :meat-balance neg?) data)]
(keep #(let [[p-start _] (first %)
[p-end {balance :meat-balance}] (last %)]
(when (neg? balance)
{:period-start p-start
:period-end p-end
:end-period-balance balance}))
parts))
;;=> ({:period-start :2007-08-06, :period-end :2007-08-07, :end-period-balance -70}
;; {:period-start :2007-08-09, :period-end :2007-08-09, :end-period-balance -10})
或包含日期的地图列表:
or a list of maps including date:
(def data [{:date :2007-08-05 :meat-weight-gain 100 :meat-weight-loss 80 :meat-balance 20},
{:date :2007-08-06 :meat-weight-gain 10 :meat-weight-loss 60 :meat-balance -30},
{:date :2007-08-07 :meat-weight-gain 40 :meat-weight-loss 80 :meat-balance -70}
{:date :2007-08-08 :meat-weight-gain 100 :meat-weight-loss 0 :meat-balance 30}
{:date :2007-08-09 :meat-weight-gain 100 :meat-weight-loss 0 :meat-balance -10}])
user> (let [parts (partition-by #(-> % :meat-balance neg?) data)]
(keep #(let [{p-start :date} (first %)
{p-end :date balance :meat-balance} (last %)]
(when (neg? balance)
{:period-start p-start
:period-end p-end
:end-period-balance balance}))
parts))
;;=> ({:period-start :2007-08-06, :period-end :2007-08-07, :end-period-balance -70}
;; {:period-start :2007-08-09, :period-end :2007-08-09, :end-period-balance -10})
更新
如果您确实需要初始数据格式,则可以使用相同的方法,只需重新定义值检索部分:
if you really need your initial data format, then you can use the same approach, just redefining values retrieval parts:
user> (defn meat-balance [rec]
(some :meat-balance (-> rec first second)))
user> (let [parts (partition-by #(-> % meat-balance neg?) data)]
(keep #(let [p-start (-> % first ffirst)
p-end (-> % last ffirst)
balance (-> % first meat-balance)]
(when (neg? balance)
{:period-start p-start
:period-end p-end
:end-period-balance balance}))
parts))
;;=> ({:period-start :2007-08-06, :period-end :2007-08-07, :end-period-balance -30})
这篇关于Clojure中的日期周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!