How do I update a vector element of an atom in Clojure?
clojure
Solution
If the indices of the vector correspond to `:id`s, you can use something like
(swap! vector-atom update-in [id] merge new-entry)
If they don't, then you have two options: (1) use a map of id -> map instead of a vector and the above simple solution, (2) use a vector and something like the following:
(swap! vector-atom
(fn [v]
(let [i (find-index-of-entry v)]
(assoc v i (merge (nth v i) new-entry)))))
`find-index-of-entry` could be a simple linear scan of the vector or, if the items are ordered by `:id`, a binary search. A linear scan will of course be dreadfully inefficient for longer vectors (and so if the vectors might be longer, switching to maps as per (1) above is a solution deserving of consideration).
Problem
I have a vector atom and I want to update an entry that is itself a map. ``` (def vector-atom (atom [])) (swap! vector-atom conj { :id 1 :name "myname" }) ``` How would I go about updating only this member? In the mindset of mutable Java land, I would do something like this: ``` (defn find-by-id [id] (first (filter (fn [entry] (= (:id entry) id)) @vector-atom))) (defn update-entry [id new-entry] (let [curr-entry (find-by-id id) merged-entry (merge curr-entry new-entry)] ###set the curr-entry to merged-entry###)) ```