How-to my case: what's the Clojure way of generating specific diff from two vectors

Hi!

I’ve got specific quite case here - while it’s easy, I’d really love to see how to do this „clojure” - and thus I am asking you for advice - how will you do this?

I’ve got two vectors made of maps: old and new. For each item (one map) with path acting as an unique key:

  1. If one map (like {:path "/etc/foo" :content "foo"}) is identical in both old and new, ommit it (nothing changed).
  2. If one map changed between old and new, return it’s version from new with additional :state :changed property: {:path "/etc/bar" :content "zar" :state :changed}
  3. If one map from old is no longer present in new, return it’s version from old with additional :state :deleted property {:path "/etc/car" :content "car" :state :deleted}.

Example:

(def old [{:path "/etc/foo"
           :content "foo"}
          {:path "/etc/bar"
           :content "bar"}
          {:path "/etc/car"
           :content "car"}])

(def old [{:path "/etc/foo"
           :content "foo"}
          {:path "/etc/bar"
           :content "zar"}])

(defn make-diff [old new]
  ...)
=>

[{:path "/etc/bar"
  :content "zar"
  :state :changed}
 {:path "/etc/car"
  :content "car"
  :state :deleted}]

Thanks!

Since you’ve got a unique key, you probably want to use a map instead of a vector:

(def old {"/etc/foo" {:path "/etc/foo"
                      :content "foo"}
          "/etc/bar"{:path "/etc/bar"
                     :content "bar"}
          ...})

Then you can iterate over the merged set of keys (clojure.set/union) and run any logic you need

1 Like

You have a few options. You can hand roll, try using EditScript or using clojure.data/diff. Using clojure.data/diff is probably is the best way to go if it works for you but EditScript is much more robust.

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.