我有一个原子:
(def data (atom[ {:orderid 0 :productid 0 :description "A" :amount 2} {:orderid 1 :productid 1 :description "A" :amount 2}]))
和我的交换功能:
(defn edit-order [params]
(filter
#(and (= (:orderid %) (:orderid params)))
@data
(swap! data (fn [old new] (merge old new)) params))
我得到的结果是:
(println (edit-order {:orderid 0 :description "edited" :amount 3}))
;=> [{:orderid 0, :productid 0, :description A, :amount 2} {:orderid 1, :productid 1, :description A, :amount 2} {:orderid 0, :description edited, :amount 3}]
我要做的是将新值更新为旧值,而不仅仅是将其添加为新值。我该怎么做?
;=> [{:orderid 0, :productid 0, :description edited, :amount 3} {:orderid 1, :productid 1, :description A, :amount 2}]
感谢您的帮助!
答案 0 :(得分:1)
解决这个问题的方法是:
(def data (atom
[{:orderid 0 :productid 0 :description "A" :amount 2}
{:orderid 1 :productid 1 :description "A" :amount 2}]))
(defn edit-order
[params]
(swap! data
(fn [old-orders]
(mapv (fn [order]
(if (= (:orderid order)
(:orderid params))
(merge order params)
order))
old-orders))))
(comment
(edit-order {:orderid 0 :description "edited" :amount 3})
#_ [{:orderid 0, :productid 0, :description "edited", :amount 3}
{:orderid 1, :productid 1, :description "A", :amount 2}]
)
请注意,您不能仅在矢量中改变一个地图。您正在基于旧的向量创建一个全新的向量,因为原子内的整个数据结构(应该)是不可变的。
答案 1 :(得分:0)
另一个选择,如果你正在进行大量的嵌套结构操作,那就是使用https://github.com/nathanmarz/specter,在这种情况下是“转换”操作。
(ns specterplay.core
(:require [com.rpl.specter :refer :all]))
(def data (atom[ {:orderid 0 :productid 0 :description "A" :amount 2} {:orderid 1 :productid 1 :description "A" :amount 2}]))
(defn edit-order!
[params data]
(swap! data
(fn [a] (transform [ALL #(= (:orderid params) (:orderid %))] #(merge % params) a))))
(edit-order! {:description "edited" :amount 3} data)
@data
;; [{:orderid 0, :productid 0, :description "edited", :amount 3} {:orderid 1, :productid 1, :description "A", :amount 2}]