我有一个矢量原子,我想更新一个本身就是地图的条目。
(def vector-atom (atom []))
(swap! vector-atom conj { :id 1 :name "myname" })
我如何才更新此会员?
在可变的Java领域的思维模式中,我会做这样的事情:
(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###))
答案 0 :(得分:12)
如果向量的索引对应:id
s,则可以使用类似
(swap! vector-atom update-in [id] merge new-entry)
如果他们没有,那么你有两个选择:(1)使用id的地图 - >映射而不是向量和上面的简单解决方案,(2)使用向量和类似下面的内容:
(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
可以是向量的简单线性扫描,如果项目按:id
排序,则可以是二进制搜索。对于较长的向量,线性扫描当然是非常低效的(因此,如果向量可能更长,则根据上述(1)切换到地图是一个值得考虑的解决方案。)