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常に「ニック」を返す関数です。

于 2012-08-17T14:56:17.767 に答える