Skip to content

Instantly share code, notes, and snippets.

@madstap
Created September 7, 2017 21:35
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 madstap/a7d158ef0c3e7b5bbf5cd55c5de4c913 to your computer and use it in GitHub Desktop.
Save madstap/a7d158ef0c3e7b5bbf5cd55c5de4c913 to your computer and use it in GitHub Desktop.
(defn merge-consecutive-by-with-xf ; this name is less than ideal...
"Returns a transducer that reduces merge-fn over consecutive values for which
(consecutive-by value) is the same."
[consecutive-by merge-fn]
(fn [rf]
(let [prev (atom ::none)]
(fn
([] (rf))
([res]
(let [p @prev]
(if (= ::none p)
(rf res)
(rf res p))))
([res x]
(let [p @prev]
(cond (= ::none p)
(do (reset! prev x)
res)
(= (consecutive-by p) (consecutive-by x))
(do (swap! prev merge-fn x)
res)
:else
(do (reset! prev x)
(rf res p)))))))))
(defn merge-peaks
"Merges two peaks, the result will retain the values of p1 but:
- :end-time will be become the value of p2
- :peak will be the concat' value of p1 and p2"
[p1 p2]
(-> p1
(update :peak
(fn [p1-peak new-peak]
(vec (concat p1-peak new-peak)))
(:peak p2))
(update :end-time
(fn [_ new-end-time] new-end-time)
(:end-time p2))))
(comment
(def test-peaks
[{:type :a
:peak [1 2]
:end-time 1}
{:type :a
:peak [3 4]
:end-time 2}
{:type :a
:peak [5 6]
:end-time 3}
{:type :b
:peak []
:end-time 8}])
;; Test
(= [{:type :a, :peak [1 2 3 4 5 6], :end-time 3}
{:type :b, :peak [], :end-time 8}]
(into [] (merge-consecutive-by-with-xf :type merge-peaks) test-peaks))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment