Skip to content

Instantly share code, notes, and snippets.

@DogLooksGood
Last active April 20, 2016 14:02
Show Gist options
  • Save DogLooksGood/1d159a28ae68f98d4615f4baf5dee15b to your computer and use it in GitHub Desktop.
Save DogLooksGood/1d159a28ae68f98d4615f4baf5dee15b to your computer and use it in GitHub Desktop.
Vector items diff and apply.
(require '[clojure.set :refer [difference intersection]])
(defn diff [x y k]
(let [xks (set (map k x))
yks (set (map k y))
y-map (zipmap (map k y) y)
x-map (zipmap (map k x) x)
cancel (difference xks yks)
commit-ks (difference yks xks)
commit (vec (vals (select-keys y-map commit-ks)))
transact-ks (filter #(not= (x-map %) (y-map %))
(intersection xks yks))
transact (select-keys y-map transact-ks)]
{:key k
:commit commit
:transact transact
:cancel cancel}))
(defn apply-diff [x d]
(let [{:keys [commit transact cancel key]} d
committed (concat x commit)
mapped (zipmap (map key committed) committed)
cancelled (apply dissoc mapped cancel)
transacted (merge cancelled transact)]
(vec (vals transacted))))
(comment
TEST BEGIN
(diff [{:db/id 1 :name "foo"}
{:db/id 2 :name "bar"}
{:db/id 3 :name "baz"}]
[{:db/id 1 :name "foo"}
{:db/id 2 :name "cat"}
{:db/id 4 :name "dog"}]
:db/id)
;; =>
;; {:key :db/id
;; :commit [{:db/id 4 ,:name "dog"}]
;; :transact {2 {:db/id 2 ,:name "cat"}}
;; :cancel #{3}}
(apply-diff [{:db/id 1 :name "foo"}
{:db/id 2 :name "bar"}
{:db/id 3 :name "baz"}]
{:key :db/id
:commit [{:db/id 4 ,:name "dog"}]
:transact {2 {:db/id 2 ,:name "cat"}}
:cancel #{3}})
;; =>
;; [{:db/id 1 :name "foo"}
;; {:db/id 2 :name "bar"}
;; {:db/id 3 :name "baz"}]
TEST END)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment