用于更新向量内部地图的clojure方法

Far*_*ion 3 clojure

什么是更新矢量中的地图的clojure方式,例如,如果我有这样的东西,假设每个地图都是唯一的 :name

(def some-vec
  [{:name "foo"
    ....}
   {:name "bar"
    ....}
   {:name "baz"
    ....}])
Run Code Online (Sandbox Code Playgroud)

如果它:name等于,我想以某种方式更新地图foo.目前我正在使用map,就像这样

(map (fn [{:keys [name] :as value}]
       (if-not (= name "foo")
         value
         (do-something .....))) some-vec)
Run Code Online (Sandbox Code Playgroud)

但是这将循环遍历整个向量,即使我只更新一个项目.

Thu*_*ail 7

将数据保存为地图而不是地图记录的矢量,键入:name.

(def some-data
  {"foo" {:name "foo" :other :stuff}
   "bar" {:name "bar" :other :stuff}
   "baz" {:name "baz" :other :stuff}})
Run Code Online (Sandbox Code Playgroud)

然后

(assoc-in some-data ["bar" :other] :things)
Run Code Online (Sandbox Code Playgroud)

产生

{"foo" {:other :stuff, :name "foo"},
 "bar" {:other :things, :name "bar"},
 "baz" {:other :stuff, :name "baz"}}
Run Code Online (Sandbox Code Playgroud)

一气呵成.

您可以捕获基本操作

(defn assoc-by-fn [data keyfn datum]
  (assoc data (keyfn datum) datum))
Run Code Online (Sandbox Code Playgroud)

例如,当

(assoc-by-fn some-data :name {:name "zip" :other :fassner})
Run Code Online (Sandbox Code Playgroud)

产生

{"zip" {:other :fassner, :name "zip"},
 "foo" {:other :stuff, :name "foo"},
 "bar" {:other :stuff, :name "bar"},
 "baz" {:other :stuff, :name "baz"}}
Run Code Online (Sandbox Code Playgroud)