Clojure (DEFM(在m ks f&;args中更新))是一种良好的做法吗?
我对clojure的世界还不熟悉,我有一个疑问。 我有一个嵌套的映射,例如Clojure (DEFM(在m ks f&;args中更新))是一种良好的做法吗?,clojure,update-in,Clojure,Update In,我对clojure的世界还不熟悉,我有一个疑问。 我有一个嵌套的映射,例如 (def accounts (hash-map :XYZ (hash-map :balance (hash-map 171000 0 :171018 500 :171025 200) :statement (hash-map :171018 [{:desc "purchase" :amount 200}
(def accounts (hash-map :XYZ (hash-map :balance (hash-map 171000 0 :171018 500 :171025 200)
:statement (hash-map :171018 [{:desc "purchase" :amount 200}
{:desc "deposit" :amount 700}]
:171025 [{:desc "purchase" :amount 300}]))
我想更新这些语句,所以我写了一个简单的函数:
(defn add-statement
[account date desc amount]
(def accounts (update-in accounts [account :statement date] conj {:desc desc :amount amount}))
但我有一种感觉,我这样做是错误的 如果要更新帐户,则需要将帐户更改为可变的。通常的方法是将帐户设置为一个
atom
。那么您的函数可能如下所示:
(defn add-statement! [account date desc amount]
(swap! accounts update-in [account :statement date]
(fn [line-items]
(conj (or line-items []) {:desc desc :amount amount}))))
这将在新日期或现有日期添加报表行项目。中的更新与您的更新相同,只是新日期的行项目将被放入向量而不是列表中。(conj
保留类型,但它必须知道类型:(conj nil:a)
给出(:a)
)
要将帐户转换为原子,请执行以下操作:
(def accounts (atom (hash-map ...)))
我注意到你的余额无论如何都不正确。但是,如果您正在更新它们,请确保在相同的交换中进行更新代码>函数
回答您的问题,“def m(在m中更新…)
是一种良好的做法吗?”。绝对不在defn
内。如果您想将def
放入defn
中,请使用让代替。在defn
之外,可以使用def
更新另一个具有不同名称的def
,因此(def m2(在m1中更新…)
) 您可以使用{}而不是哈希映射,例如:{:XYZ{:balance….}}很好,谢谢您的回答。这是我的第一次尝试,我想在第二次尝试中使用ref(同时进行交易和更新多个帐户)