Skip to content

Instantly share code, notes, and snippets.

@geraldodev
Created May 3, 2015 22:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save geraldodev/daae851568894538cdc6 to your computer and use it in GitHub Desktop.
Save geraldodev/daae851568894538cdc6 to your computer and use it in GitHub Desktop.
(ns util.map
(:require [schema.core :as s]
[clojure.set :as set]
[clojure.data :refer [diff]]
[clojure.pprint :refer [pprint]]))
(s/def TAnyMap {s/Any s/Any})
(s/defn diff-by-key :- [(s/one TAnyMap "included")
(s/one TAnyMap "excluded")
(s/one {s/Any [(s/one s/Any "before")
(s/one s/Any "after")]} "modified")]
"Compares two maps by keys returning a vector of three items
first- map with included keys with the values verbatim
second - map with excluded keys with the values verbatim
third - map of keys that had its values modified. the values of this map are vectors of two items [before-value after-value]
"
[m-a :- TAnyMap
m-b :- TAnyMap]
(let [keys-a (set (keys m-a))
keys-b (set (keys m-b))
included-keys (set/difference keys-b keys-a)
excluded-keys (set/difference keys-a keys-b)
]
[(select-keys m-b included-keys)
(select-keys m-a excluded-keys)
(->> m-b
(filter (fn [[k v]]
(and (not (included-keys k))
(not (excluded-keys k))
(not= v (get m-a k)))))
(map (fn [[k v]]
(let [v-a (get m-a k)
dif-v (diff v-a v)
dif-m (->> (second dif-v)
(map (fn [[kk vv]]
[kk [(get v-a kk) vv]]))
(reduce (fn [m [kk vv]]
(assoc m kk vv))
{}))]
[k dif-m])))
(reduce (fn [m [k v]]
(assoc! m k v))
(transient {}))
(persistent!))]))
(comment
(pprint (diff-by-key {"01" {:codigo "01" :nome "Joao"}
"02" {:codigo "02" :nome "Maria"}
"03" {:codigo "03" :nome "pedro"}}
{"01" {:codigo "01" :nome "Joao da silva"}
"02" {:codigo "02" :nome "Maria"}
"04" {:codigo "04" :nome "mariana"}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment