我有一个这样的数据结构:
[{ :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}]}]
我如何迭代它并返回肉类余额为负时的数据周期?示例数据如下所示:
[ {:end-period-balance -70, :period-start 2007-08-06, :period-end 2007-08-07 } ]
除此之外,我可以改进我的数据结构还是已经可以了?如果是,怎么办?非常感谢。
最佳答案
我建议您将数据形状更改为元组列表,每个元组包含日期和余额数据图。就像这样:
(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}]])
然后就可以很容易地按体重增加/减少对周期进行分类(使用partition-by
)并收集所需的信息:
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})
或包含日期的 map 列表:
(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})
更新
如果您确实需要初始数据格式,那么您可以使用相同的方法,只需重新定义值检索部分:
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})
关于vector - Clojure 中的日期周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44232718/