lisp - Clojure: iterate over map of sets -
this pretty follow-up last question (clojure idiomatic way update multiple values of map), not quite same. (keep in mind i'm new clojure , functional languages alike)
suppose have following data structure, defined map of sets:
(def m1 {:1 #{2} :2 #{1 3} :3 #{1}}) and map of maps such:
(def m2 {:1 {:1 0 :2 12 :3 23} :2 {:1 23 :2 0 :3 4} :3 {:1 2 :2 4 :3 0}}) what want update registries of m2 have correspondence in m1 value. let's value want x. resulting m2 this:
{:1 {:1 0 :2 x :3 23} :2 {:1 x :2 0 :3 x} :3 {:1 x :2 4 :3 0}} assuming v contains every possible key map, y first attempt, (that failed miserably) this: (assume x=1
(for [i v] reduce (fn [m j] (assoc-in m [i j] 1)) d (i m1))) needless failure. so, how idiomatic way this?
as understand requirements want to
- produce number of key-sequences
m1. - in
m2associate each of key-sequences particular constant value.
the first step simple transformation of m1. want produce 0 or more key-seqs each entry (depending on how many in set), natural go-to me mapcat. stands map-then-concat , great such case each element of seq produce 0 or more of elements want.
(defn key-seqs [coll] (mapcat (fn [[k v]] (map (partial vector k) v)) coll)) (key-seqs m1) ;;=> ([:1 2] [:2 1] [:2 3] [:3 1]) note function taken mapcat map, produces sequence (possibly empty) mapcat unroll. returning longs stored in sets themselves. if want turn them keywords match m2 need little more processing:
(defn key-seqs [coll] (mapcat (fn [[k v]] (map (comp (partial vector k) keyword str) v)) coll)) (key-seqs m1) ;;=> ([:1 :2] [:2 :1] [:2 :3] [:3 :1]) (we need use str because keyword doesn't know longs. keywords not numbers, names symbolic meaning)
then can adapt update-m previous question little bit can take constant value argument , handle key-sequences don't have same value twice:
(defn update-m [m x v] (reduce (fn [m' key-seq] (assoc-in m' key-seq x)) ;; accumulate changes m ;; initial-value v)) ;; collection loop on and seem in business:
(update-m m2 1 (key-seqs m1)) ;;=> {:1 {:1 0, :2 1, :3 23}, :2 {:1 1, :2 0, :3 1}, :3 {:1 1, :2 4, :3 0}}
Comments
Post a Comment