6

鉴于以下情况:

(defrecord Person [firstname lastname])
(def some-map (ref {}))

(dosync
  (alter some-map conj {1 (Person. "john" "doe")})
  (alter some-map conj {2 (Person. "jane" "jameson")}))

要将“joe”的名字更改为“nick”,我执行以下操作:

(dosync
  (alter some-map (fn [m]                   
                  (assoc m 1 
                       (assoc (m 1) :firstname "nick")))))

在 Clojure 中这样做的惯用方式是什么?

4

2 回答 2

5

无需使用 update-in,对于这种情况, assoc-in 正是您想要的。

(dosync (alter some-map assoc-in [1 :firstname] "nick"))

于 2012-08-17T14:57:46.060 回答
2

编辑:对于您的示例assoc-in更好,因为您忽略了以前的值。在您实际需要先前值的情况下保留此答案:

update-in可以更新嵌套结构:

(alter some-map update-in [1 :firstname] (constantly "nick"))

最后一个参数是要“替换”的值的函数(例如assoc,它不替换但返回一个新结构。)在这种情况下,旧值被忽略,因此constantly函数总是返回“nick”。

于 2012-08-17T14:56:17.767 回答