简体   繁体   English

(def m(update in in ks f&args))是一个好习惯吗?

[英]Is (def m (update-in m ks f & args)) a good practice?

I'm new to the world of clojure and I have a doubt. 我是Clojure领域的新手,我对此表示怀疑。 I have a nested map such as 我有一个嵌套的地图,例如

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

And I want to update the statements, so I wrote a simple function: 而且我想更新语句,所以我写了一个简单的函数:

(defn add-statement
[account date desc amount]
(def accounts (update-in accounts [account :statement date] conj {:desc desc :amount amount}))

But I have a feeling that I'm doing that the wrong way... 但是我有一种错误的感觉...

You would need to change accounts to be mutable if you want to update them. 如果要更新accounts ,则需要将其更改为可变accounts The usual way to do this is by making accounts an atom . 通常的方法是使帐户成为atom Then your function might look like this: 然后您的函数可能如下所示:

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

This will add a statement line-item at a new or an existing date. 这将在新的或现有的日期添加一个语句行项目。 The update-in is the same as yours, except that a line-item for a new date will be put into a vector rather than a list. update-in与您的update-in相同,只是将新日期的行项目放入向量而不是列表中。 ( conj keeps the type, but it has to know the type: (conj nil :a) gives (:a) ). conj保留类型,但必须知道类型: (conj nil :a)给出(:a) )。

To turn accounts into an atom: 要将账户变成原子:

(def accounts (atom (hash-map ...)))

I notice your balances are not correct anyway. 我注意到您的余额仍然不正确。 But if you are updating them be sure to do so in the same swap! 但是,如果要更新它们,请确保在同一swap! function. 功能。

To answer your question, "Is (def m (update-in m ...)) a good practice?". 要回答您的问题,“ (def m (update-in m ...))是好的做法吗?”。 Definitely not inside a defn . 绝对不在defn内部。 If you are thinking to put a def inside a defn use a let instead. 如果您想将def放入defn使用let代替。 Outside of a defn it would be fine to have a def that updates another def that has a different name, so (def m2 (update-in m1 ...)) . 一个外defn这将是罚款,有一个def ,更新另一个def具有不同的名称,所以(def m2 (update-in m1 ...))

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

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