Clojure:如何更新映射中的多个值
我有一个包含多个计数器的地图,例如:Clojure:如何更新映射中的多个值,clojure,Clojure,我有一个包含多个计数器的地图,例如: (def m1 (atom {:counter1 10 :counter2 3 :counter3 11})) ;;;=> {:counter1 10, :counter3 11, :counter2 3} 我想将计数器2增加一,并将计数器1和计数器3重置为零 我似乎想不出一个办法来做这件事。我遇到的最好的函数是下面的函数。但是,此函数不会将计数器1和计数器3重置回零,只是不会增加它们 (swap! m1 (fn [m] (m
(def m1 (atom {:counter1 10 :counter2 3 :counter3 11}))
;;;=> {:counter1 10, :counter3 11, :counter2 3}
我想将计数器2增加一,并将计数器1和计数器3重置为零
我似乎想不出一个办法来做这件事。我遇到的最好的函数是下面的函数。但是,此函数不会将计数器1和计数器3重置回零,只是不会增加它们
(swap! m1 (fn [m]
(merge-with + m {:counter1 0
:counter2 1
:counter3 0})))
;;;=> {:counter1 10, :counter3 11, :counter2 4}
是否可以通过一次交换来实现我的要求!,或者我需要通过调用swap来实现!和多次重置 那么,您可以修改代码来完成此操作,方法是将
合并中的+
替换为另一个函数:
(defn my-plus [old new] (if (pos? new) (+ new old) 0))
我仍在考虑一种不同的解决方法。保持简单!使用普通的合并
并再次从地图访问:counter 2
(swap! m1 (fn [m]
(merge m {:counter1 0
:counter2 (-> m :counter2 inc)
:counter3 0})))
或将两个操作分开:
(swap! m1 #(-> %
(update :counter2 inc)
(assoc :counter1 0 :counter3 0)))
编辑
如果您使用的是<1.7 Clojure版本,请使用迄今为止最惯用的解决方案,而不是。对于(waaay)比这更复杂的转换,可能有用。update是一个单独的函数,它以键和函数(在本例中为inc)作为参数吗?还有一个后续问题,为什么我们不能在assoc中增加:counter2?@sakh1979我添加了更新(-in)文档链接<代码>关联
仅关联值-它不接受函数。使用assoc
的方法基本上与所建议的@QuickBrownFox相同(s/merge m{/assoc m/
)