簡體   English   中英

減少clojure的分組

[英]group-by with reduce in clojure

我想聚合大型數據集以獲得類似

SELECT SUM(`profit`) as `profit`, `month` FROM `t` GROUP BY `month`

所以,我像這樣修改了clojure的分組功能

(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)))

這是用法:

(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}}

它可以工作,但是使用clojure標准庫可能還有另一種方法嗎?

核心中最接近的是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}

一些例子:

user=> (def groups (group-by :month [{:month 10 :profit 12}
  #_=>                               {:month 10 :profit 15}
  #_=>                               {:month 12 :profit 1}])
{10 [{:profit 12, :month 10} {:profit 15, :month 10}], 12 [{:profit 1, :month 12}]}

user=> (for [[k v] groups] {:month k :sum-profit (apply + (map :profit v))})
({:month 10, :sum-profit 27} {:month 12, :sum-profit 1})

user=> (into {} (for [[k v] groups] [k (apply + (map :profit v))]))
{10 27, 12 1}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM