Clojurescript:如何有条件地更新哈希映射?
Clojurescript: How to conditionally update a hash map?
我正在尝试了解一些 CLJS 和 Reagent,但当我尝试对原子应用一个或另一个更新时,我 运行 遇到了问题。
我有一个递增函数,incDieCount
,它递增映射中特定键的值。我试图编写一个函数,它也应该减少一个键的值。它在值为 0 时起作用(它不会递减到该值以下),但不是将当前值递减 1,而是 always 将值设置为零。我错过了什么?
(defonce app-state
(reagent/atom
{:dice
{:d4 0
:d6 0
:d8 0
:d10 0
:d12 0
:d20 0
:d100 0}}))
(defn incDieCount [die]
#(swap! app-state update-in [:dice die] inc))
(defn decDieCount [die]
(let [count (get-in app-state [:dice die])]
(if (> 0 count)
#(swap! app-state update-in [:dice die] dec)
#(swap! app-state assoc-in [:dice die] 0))))
(defn diceEl [[die count]]
^{:key die} [:li
(str (name die) ": " count)
[:button {:on-click (incDieCount die)}
"Add"]
[:button {:on-click (decDieCount die)}
"Subtract"]])
(defn page [ratom]
[:ul
(for [tuple (:dice @ratom)] (diceEl tuple))])
(defn reload []
(reagent/render [page app-state]
(.getElementById js/document "app")))
(defn ^:export main []
(dev-setup)
(reload))
要获取原子的当前值,您需要取消引用它:@app-state
。
(let [count (get-in @app-state [:dice die])] ...)
添加@Ming 的回答:首先,您需要 (> count 0)
而不是 (> 0 count)
- 后者转换为 count < 0
.
其次,不建议非原子地使用原子 - 在您的 decDieCount
代码中,条件 count > 0
在呈现组件时检查,而不是在单击按钮时检查(什么如果骰子的值在两者之间发生变化?)
最好将decDieCount
改写如下:
(defn decDieCount [die]
(fn []
(swap! app-state update-in [:dice die]
#(if (pos? %) (dec %) 0))))
这样可以保证骰子的新值基于其当前值。
我正在尝试了解一些 CLJS 和 Reagent,但当我尝试对原子应用一个或另一个更新时,我 运行 遇到了问题。
我有一个递增函数,incDieCount
,它递增映射中特定键的值。我试图编写一个函数,它也应该减少一个键的值。它在值为 0 时起作用(它不会递减到该值以下),但不是将当前值递减 1,而是 always 将值设置为零。我错过了什么?
(defonce app-state
(reagent/atom
{:dice
{:d4 0
:d6 0
:d8 0
:d10 0
:d12 0
:d20 0
:d100 0}}))
(defn incDieCount [die]
#(swap! app-state update-in [:dice die] inc))
(defn decDieCount [die]
(let [count (get-in app-state [:dice die])]
(if (> 0 count)
#(swap! app-state update-in [:dice die] dec)
#(swap! app-state assoc-in [:dice die] 0))))
(defn diceEl [[die count]]
^{:key die} [:li
(str (name die) ": " count)
[:button {:on-click (incDieCount die)}
"Add"]
[:button {:on-click (decDieCount die)}
"Subtract"]])
(defn page [ratom]
[:ul
(for [tuple (:dice @ratom)] (diceEl tuple))])
(defn reload []
(reagent/render [page app-state]
(.getElementById js/document "app")))
(defn ^:export main []
(dev-setup)
(reload))
要获取原子的当前值,您需要取消引用它:@app-state
。
(let [count (get-in @app-state [:dice die])] ...)
添加@Ming 的回答:首先,您需要 (> count 0)
而不是 (> 0 count)
- 后者转换为 count < 0
.
其次,不建议非原子地使用原子 - 在您的 decDieCount
代码中,条件 count > 0
在呈现组件时检查,而不是在单击按钮时检查(什么如果骰子的值在两者之间发生变化?)
最好将decDieCount
改写如下:
(defn decDieCount [die]
(fn []
(swap! app-state update-in [:dice die]
#(if (pos? %) (dec %) 0))))
这样可以保证骰子的新值基于其当前值。