Clojure:地图中的聚合和计数

前端之家收集整理的这篇文章主要介绍了Clojure:地图中的聚合和计数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想这个问题可以作为入门级的clojure问题.我基本上有多次麻烦地处理一个clojure地图并提取不同类型的数据.

给定这样的映射,我试图基于多个嵌套键来计算条目:

[
  {
    "a": "X","b": "M","c": 188
  },{
    "a": "Y","c": 165
  },"c": 313
  },"b": "P","c": 188
  }
]

首先,我想通过a键值对条目进行分组:

{
  "X" : [
    {
      "b": "M","c": 188
    }
  ],"Y" : [
    {
      "b": "M","c": 165
    },{
      "b": "M","c": 313
    },{
      "b": "P","c": 188
    }
  ]
}

其次,我想假设b键的值是重复的,并忽略其余的键:

{
  "X" : [
    {
      "b": "M"
    }
  ],"Y" : [
    {
      "b": "M"
    }
    {
      "b": "P"
    }
  ]
}

然后,只需计算b键的所有实例:

{
  "X" : 1,"Y" : 2
}

当我通过monger获取数据时,我定义了:

(defn db-query
  ([coll-name]
     (with-open [conn (mg/connect)]
       (doall (mc/find-maps (mg/get-db conn db-name) coll-name))))

然后点击路障:

(defn get-sums [request]
  (->> (db-query "data")
       (group-by :a)
       (into {})
        keys))

我怎么能从这里继续?

解决方法

这是一种天真的方法,我相信有更好的方法,但它可能是你需要弄清楚的.

(into {}
  (map       

    ; f       
    (fn [ [k vs] ] ;[k `unique count`]
      [k (count (into #{} (map #(get % "b") vs)))]) 

    ; coll
    (group-by #(get % "a") DATA))) ; "a"s as keys
;user=> {"X" 1,"Y" 2}

说明:

; I am using your literal data as DATA,just removed the,and ;
(def DATA [{...

(group-by #(get % "a") DATA) ; groups by "a" as keys
; so I get a map {"X":[{},...] "Y":[{},{},...]}

; then I map over each [k v] pair where
; k is the map key and
; vs are the grouped maps in a vector
(fn [ [k vs] ] 
      ; here `k` is e.g. "Y" and `vs` are the maps {a _,b,_,c _}

      ; now `(map #(get % "b") vs)` gets me all the b values
      ; `into set` makes them uniqe
      ; `count` counts them
      ; finally I return a vector with the same name `k`,;   but the value is the counted `b`s
      [k (count (into #{} (map #(get % "b") vs)))]) 

; at the end I just put the result `[ ["Y" 2] ["X" 1] ]` `into` a map {}
; so you get a map

猜你在找的设计模式相关文章