vector - Clojure 中的日期周期

标签 vector clojure

我有一个这样的数据结构:

[{ :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/

相关文章:

C++:如何获取 vector 来打印用户输入?

C++ 对象和线程

clojure - 是否有 if-clojurescript 宏?

clojure - 为什么 (every? string? []) 应该产生 true ?

c++ - 如何有一个 vector 的复制构造函数?

data-structures - 链表与向量

c++ - 我可以创建具有指定长度但没有初始化的 C++ 字符串/vector 吗?

Clojure - 自动更新列表框

haskell - Haskell 的 <- 的 clojure 等价物是什么?

clojure - 在 Clojure 中将单参数函数合并为多参数函数