我对克洛尔的世界并不熟悉,我有一个疑问。我有一个嵌套的映射,如
(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}))但我有种感觉我这样做是错误的.
发布于 2017-10-28 22:40:17
如果要更新accounts,则需要将它们更改为可变的。做这件事的通常方法是把帐户变成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}))))这将在新日期或现有日期添加语句行项。update-in与您的相同,只是新日期的行项将被放入向量而不是列表。(conj保留类型,但它必须知道类型:(conj nil :a)给出了(:a))。
把帐户变成原子:
(def accounts (atom (hash-map ...)))我注意到你的余额是不正确的。但是,如果要更新它们,请确保在相同的swap!函数中这样做。
回答你的问题,“(def m (update-in m ...))是一个好的实践吗?”绝对不是在defn里面。如果您正在考虑将def放入defn中,则使用let代替。在defn之外,如果有一个def来更新另一个具有不同名称的def,那么(def m2 (update-in m1 ...))就可以了。
https://stackoverflow.com/questions/46995006
复制相似问题