如何更新Clojure中的原子的向量元素? [英] How do I update a vector element of an atom in Clojure?

查看:244
本文介绍了如何更新Clojure中的原子的向量元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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?

在可变Java土地的心态,我会做这样的:

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


推荐答案

如果向量的索引对应于:id s,可以使用

If the indices of the vector correspond to :ids, you can use something like

(swap! vector-atom update-in [id] merge new-entry)

如果他们没有,那么你有两个选择:(1) > map而不是一个向量和上面的简单的解决方案,(2)使用一个向量和像下面的东西:

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 可以是向量的简单线性扫描,或者如果项目按:id 排序,则为二分搜索。对于较长的向量,线性扫描当然是可怕的低效的(因此,如果向量可能更长,根据上述(1)切换到映射是一种值得考虑的解决方案)。

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).

这篇关于如何更新Clojure中的原子的向量元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆