Nate wants to see more than data structures in a REPL.
filter
then map
, then reduce
split-weeks
in the Clojure cheat sheet.":sunday
, :tuesday
, etc.group-by
the week:
(week-id starting-day-of-week day)
(week-id :sunday {:date "2019-03-08" ...}) => "2019-03-03"
println
.println
a trivial step at the endprintln
could be tested, even the formatting!Related episodes:
Clojure in this episode:
filter
, map
, reduce
group-by
sort-by
with partition-by
take-while
, drop-while
, and split-with
Code sample from this episode:
(ns time.week-05
(:require
[time.week-04 :as week-04]
[java-time :as jt]
))
; Date helpers
(defn start-of-week
"Get the the starting date of the week containing local-date. The week will
start on the named day. Eg. :sunday"
[starting-day-of-week local-date]
(jt/adjust local-date :previous-or-same-day-of-week (jt/day-of-week starting-day-of-week)))
(defn week-dates
"Create a week's worth of dates starting from the given date."
[starting-date]
(->> (range 0 7)
(map #(jt/plus starting-date (jt/days %)))))
; Aggregates
(defn sum-minutes
"Sums the minutes for all kinds: entry, day, week"
[entries]
(->> entries
(map :minutes)
(reduce +)))
; Conversions
(defn entries->days
"Convert a seq of entries to days."
[entries]
(->> (group-by :date entries)
(map (fn [[date xs]] {:date date :minutes (sum-minutes xs)}))))
(defn days->week
"Convert a seq of days into a week. Week is picked by first date."
[starting-day-of-week days]
(let [lookup (into {} (map (juxt :date identity) days))
starting-date (start-of-week starting-day-of-week (:date (first days)))
all-days (->> (week-dates starting-date)
(map #(or (get lookup %)
{:date %
:minutes 0})))]
{:starting-day-of-week starting-day-of-week
:date starting-date
:days (vec all-days)
:minutes (sum-minutes all-days)}))
(defn partition-weeks
[starting-day-of-week days]
(->> days
(sort-by :date)
(partition-by #(start-of-week starting-day-of-week (:date %)))))
(defn days->weeks
"Convert a seq of days into an ordered seq of weeks."
[starting-day-of-week days]
(->> (partition-weeks starting-day-of-week days)
(map (partial days->week starting-day-of-week))))
(comment
(->> (week-04/log-times "time-log.txt")
(entries->days))
(->> (week-04/log-times "time-log.txt")
(entries->days)
(days->weeks :sunday))
)