首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >clojure中的group-by with reduce

clojure中的group-by with reduce
EN

Stack Overflow用户
提问于 2013-03-22 18:56:04
回答 2查看 1.3K关注 0票数 4

我想要聚合大型数据集,以获得如下内容

代码语言:javascript
复制
SELECT SUM(`profit`) as `profit`, `month` FROM `t` GROUP BY `month`

因此,我修改了clojure的group-by函数,如下所示

代码语言:javascript
复制
(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)))

下面是用法:

代码语言:javascript
复制
(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标准库?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-24 05:26:01

最接近核心的是merge-with

代码语言:javascript
复制
(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}
票数 5
EN

Stack Overflow用户

发布于 2013-03-22 19:44:39

下面是一些例子:

代码语言:javascript
复制
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}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15568588

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档