Clojure中的日期周期 [英] Date periods in clojure

查看:84
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆