如何在Clojure中更新原子的向量元素?

时间:2014-02-14 06:52:45

标签: clojure

我有一个矢量原子,我想更新一个本身就是地图的条目。

(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###))

1 个答案:

答案 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)切换到地图是一个值得考虑的解决方案。)