2017-10-28 6 views
1

私はclojureの世界には新しく、疑いがあります。 は、私は、ネストされたマップなど(def m(m-ks f&args)の更新)は良い方法ですか?

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

をしかし、私は私が間違っていることをやっている感じを持っていますway ...

+0

などのハッシュマップの代わりに{}を使用できます。{:XYZ {:balance ....}} –

答えて

2

更新する場合は、accountsを変更可能にする必要があります。これを行う通常の方法は、アカウントを​​にすることです。次に、あなたの関数は次のようになります。

(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の内部にはありません。 defdefnに入れようと考えているのであれば、代わりにletを使用してください。 defnの外にdefを追加すると、別の名前のdefが更新されます((def m2 (update-in m1 ...)))。

+0

答えに感謝します。それは私の最初の試行です、私は2回目の試行でref(トランザクションを作成し、同時にいくつかのアカウントを更新する)を使うことを考えていました – Darakt

関連する問題