日历矢量的clojure重构

时间:2014-08-17 05:53:27

标签: clojure

我提出了以下功能,当给定开始日期时,将返回5个向量,每个向量为7天。

您可以将此视为任何日历月,通常显示如下:

(defn weeks [start-date]
  (for [week-counter (range 0 35 7)]
    (vec (for [day-counter (range 7)]
      (->
       start-date
       (.clone)
       (.add "days" (+ week-counter day-counter))
       (.format date-format))))))

我是clojure的新手,我很想知道其他方法。

1 个答案:

答案 0 :(得分:1)

我很想表达这样的话:

(defn weeks [start-date]
  (letfn [(compose [n] (->  start-date
                           (.clone)
                           (.add "days" n)
                           (.format date-format)))]
    (map vec (partition 7 (map compose (range (* 7 5)))))))

但这是你想要的吗?例如,如果我们简化compose函数...

(defn weeks [start-date]
  (letfn [(compose [n] (str start-date " " n))]
    (map vec (partition 7 (map compose (range (* 7 5)))))))

...然后,例如,

(weeks "august")

...生产

(["august 0"
  "august 1"
  "august 2"
  "august 3"
  "august 4"
  "august 5"
  "august 6"]

   ...

 ["august 28"
  "august 29"
  "august 30"
  "august 31"
  "august 32"
  "august 33"
  "august 34"])

我觉得很难想到这个用途。


如果您想要每周一个月的日期,您需要知道

  • 该月的第一天所在的那一天 - 一个数字 从0到6;
  • 当月的天数。

生成模式的函数是

(defn week-pattern [start-day days-in-month]
  (take-while
    (partial some identity)
    (partition 7 (concat (repeat start-day nil)
                         (range days-in-month)
                         (repeat nil)))))

例如,今年6月开始于星期日,即第6天(如果一周从星期一开始),所以跨越六周,但只有三十天:

=> (week-pattern 6 30)

((nil nil nil nil nil nil 0)
 (1 2 3 4 5 6 7)
 (8 9 10 11 12 13 14)
 (15 16 17 18 19 20 21)
 (22 23 24 25 26 27 28)
 (29 nil nil nil nil nil nil))

以此为模板,您可以向map和/或map-indexed添加函数参数,以随意播放内容。

我已经按照你的用法计算了从零开始的月份,而不是真正的日历。如果您想从1开始计算,请将(range days-in-month)替换为(range 1 (inc days-in-month))


如果您可以选择,请考虑使用Joda-Time等库,将日期视为不可变值。