Skip to content

Instantly share code, notes, and snippets.

@ahoy-jon
Created October 6, 2013 16:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ahoy-jon/f15508509e183b5e9bc3 to your computer and use it in GitHub Desktop.
Save ahoy-jon/f15508509e183b5e9bc3 to your computer and use it in GitHub Desktop.
(use '[clojure.core.match :only (match)])
(defn contextualize
"take a map m, and create a deep map from it, based on the sequence of keys in kvec
(= (contextualize [[:a :b] [:c]] {:a 1 :b 2 :c 3}) {{:a 1 :b 2} {:c 3}})
"
[kvec data]
(match [kvec]
[([f] :seq)] (select-keys data f)
[([f & r] :seq)] {(select-keys data f) (contextualize r data)}))
(contextualize [[:c] [:b :d] [:a]] {:a 1 :b 2 :c 3 :d 4})
(defprotocol Mono
(mono [a b] "accumulate b in a"))
(extend-protocol Mono
clojure.lang.IPersistentMap
(mono [m1 m2] (merge-with mono m1 m2))
Number
(mono [m1 m2] (+ m1 m2)))
(mono {:a 1} {:b 2 :a 1})
(mono (array-map :a 1) (hash-map :b 2 :a 1))
(def data [{:date #inst "2013-09-30" :who "Jon" :buyed "Coffe" :for {:euros 6}}
{:date #inst "2013-09-30" :who "Jon" :buyed "A Book" :for {:dollars 35}}
{:date #inst "2013-09-30" :who "Maximilien" :buyed "Coffe" :for {:francs 1}}
{:date #inst "2013-10-01" :who "Jon" :buyed "Coffe" :for {:euros 5}}
{:date #inst "2013-10-01" :who "Jon" :buyed "A kinder bueno" :for {:euros 2}}
{:date #inst "2013-10-01" :who "Maximilien" :buyed "A Book" :for {:francs 100}}
{:date #inst "2013-10-01" :who "Maximilien" :buyed "Coffe" :for {:francs 2}}
])
(defn query
([kvec] (query kvec identity))
([kvec pre-map]
(->> data
(map (comp (partial contextualize kvec) pre-map))
(reduce mono))))
;; total per day
(query [[:date] [:for]])
;; count item per person, per day
(query [[:who] [:date] [:count]] #(assoc % :count 1))
;; group by people + item
(query [[:who :buyed] [:for]])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment