Skip to content

Instantly share code, notes, and snippets.

@Kah0ona
Created September 7, 2017 19:39
Show Gist options
  • Save Kah0ona/789d2daf0cae1a9773f0a652272723b5 to your computer and use it in GitHub Desktop.
Save Kah0ona/789d2daf0cae1a9773f0a652272723b5 to your computer and use it in GitHub Desktop.
Transducer that merges consecutive elements if they are similar
(declare merge-peak-with-first)
(defn concatenate-similar-peaks-xf []
(fn [xf]
(let [prev (volatile! ::none)]
(fn
([] (xf))
([result] (xf result))
([result input]
(let [prior @prev]
(vreset! prev input)
(if (= (:type prior) (:type input))
;;same type, merge the two peak-maps prior and input,
;;else, keep processing
(-> result
pop ;; <-- !!! pop and conj are too specific functions that deal on collections.
;; What should I do to make this work?
(conj (merge-peak-with-first prior input)))
(xf result input))))))))
(defn merge-peak-with-first
"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))))
;; Usage below
;; ===========
(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])
;; I want the result to be:
;; [{:type :a :peak [1 2 3 4 5 6] :end_time 3}
;; {:type :b :peak [] :end_time 8}]
(into [] (concatenate-similar-peaks-xf) test-peaks)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment