public
Last active

Map mixer

  • Download Gist
gistfile1.clj
Clojure
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
(def aap {"Toby" {"Batman begins" 4.5
"TDKR" 5.0}
"Lisa" {"Batman begins" 5.0
"Spiderman" 4.5}})
 
(defn order-seq [order values]
(let [val-vec (vec values)]
(reduce (fn [v idx]
(conj v (get val-vec idx)))
[] order)))
 
(defmacro map-mixer [order]
(let [n (count order)
map-sym (gensym)
values-sym (gensym)
key-syms (take (dec n) (repeatedly gensym))
val-syms (cons values-sym (take (dec n) (repeatedly gensym)))]
(letfn [(outside-in [[k & ks] [v1 v2 :as vs] m]
(if k
`(reduce (fn [~map-sym [~k ~v2]]
~(outside-in ks (rest vs) map-sym))
~m ~v1)
`(assoc-in ~map-sym
~(order-seq (drop-last order) key-syms)
~(last val-syms))))]
`(fn [~values-sym]
~(outside-in key-syms val-syms {})))))
 
(defn transform-perfs [perfs]
(reduce (fn [m [person scores]]
(reduce (fn [m [movie score]]
(assoc m movie (assoc (get m movie {}) person score)))
m scores)) {} perfs))
 
(defn transform-perfs2 [perfs]
(reduce (fn [m [person scores]]
(reduce (fn [m [movie score]]
(assoc-in m [movie person] score))
m scores)) {} perfs))
 
(def transform-perfs3 (map-mixer [1 0 2]))
 
(defn -main
[& args]
(println (transform-perfs aap))
(println (transform-perfs2 aap))
(println (transform-perfs3 aap)))

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.