Skip to content

Instantly share code, notes, and snippets.

@henryw374
Last active February 5, 2021 06:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save henryw374/7d117fc98c13541f13e5939f0e1494d0 to your computer and use it in GitHub Desktop.
Save henryw374/7d117fc98c13541f13e5939f0e1494d0 to your computer and use it in GitHub Desktop.
(ns com.widdindustries.timelines
"create timelines which are (possibly infinite) sequences of maps with a ::time key.
Multiple timelines can be merged into a single timeline
Zero dependency - BYO time lib
Demo in comment at the end
")
(defn merge-timelines [timelines]
(let [[tl-with-soonest & others] (sort-by (comp ::time first) (remove nil? timelines))
[next-soonest & remainder] tl-with-soonest]
(if-not next-soonest
[]
(lazy-seq
(cons next-soonest
(merge-timelines (cons remainder others)))))))
(defn timeline [{:keys [start
end-pred next-tick]}]
(let [tl (iterate (fn [prev]
(update prev ::time
next-tick))
start)]
(if end-pred
(take-while #(end-pred (::time %))
tl)
tl)))
(comment
(require '[tick.alpha.api :as t])
(def foo-timeline
(timeline {:start {::time (t/today)
:timeline-name "foo"}
:next-tick (fn [x] (t/>> x (t/new-period 2 :days)))}))
(def bar-timeline
(timeline {:start {::time (t/yesterday)
:timeline-name "bar"}
:next-tick (fn [x] (t/>> x (t/new-period 1 :days)))
:end-pred (fn [x] (t/<= x (t/>> (t/today)
(t/new-period 4 :days))))}))
; see bar is finite - only 6 in the seq
(take 10 bar-timeline)
(def foo-bar-timeline (merge-timelines [foo-timeline bar-timeline]))
; see foo and bar interleaved
(take 10 foo-bar-timeline)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment