简体   繁体   English

如何更新Clojure中ref地图中的记录?

[英]How to update records in a ref map in Clojure?

Given the following scenario: 鉴于以下情况:

(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")}))

To change the firstname of "joe" to "nick", I do the following: 要将“joe”的名字改为“nick”,我会执行以下操作:

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

What is the idiomatic way of doing this in Clojure? 在Clojure中这样做的惯用方法是什么?

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

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

Edit: For your example assoc-in is better, since you ignore the previous value. 编辑:对于您的示例, assoc-in更好,因为您忽略了以前的值。 Keeping this answer for cases where you actually need the previous value: 在实际需要以前值的情况下保留此答案:

The update-in is there to update nested structures: update-in用于更新嵌套结构:

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

The last argument is a function on the value to be "replaced" (like assoc , it does not replace but returns a new structure.) In this case the old value is ignored, hence the constantly function that always returns "nick". 最后一个参数是要被“替换”的值的函数(如assoc ,它不替换但返回一个新结构。)在这种情况下,旧值被忽略,因此常常返回“nick”的constantly函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM