group-by with reduce in clojure

clojure, group-by, reduce

Solution

Closest in the core is `merge-with`:

(def t [{:month 10 :profit 12}
        {:month 10 :profit 15}
        {:month 12 :profit 1}])

(apply merge-with + (for [x t] {(:month x) (:profit x)}))
;=> {12 1, 10 27}

Problem

I want to aggregate large dataset to get something like ``` SELECT SUM(`profit`) as `profit`, `month` FROM `t` GROUP BY `month` ``` So, i modified clojure's group-by function like so ``` (defn group-reduce [f red coll] (persistent! (reduce (fn [ret x] (let [k (f x)] (assoc! ret k (red (get ret k) x)))) (transient {}) coll))) ``` And here is usage: ``` (group-reduce :month (fn [s x] (if s (assoc s :profit (+ (:profit s) (:profit x))) x)) [{:month 10 :profit 12} {:month 10 :profit 15} {:month 12 :profit 1}]) #_=> {10 {:profit 27, :month 10}, 12 {:profit 1, :month 12}} ``` It works, but maybe there is another way to do this, using clojure standard library?

Original source