如何更新原子中的试剂向量
How to update Reagent vector in an atom
我有一个试剂原子:
(defonce order (r/atom {:firstName "" :lastName "" :toppings [] }))
我想在 :toppings
向量中添加浇头。我尝试了很多变体:
(swap! (:toppings order) conj "Pepperoni")
这给了我:Uncaught Error: No protocol method ISwap.-swap! defined for type null:
(swap! order :toppings "Pepperoni")
有点像,但只是更新顺序,而不是 :toppings
向量。当我取消引用 order
时,我只得到最新的值。
向我的 :toppings
向量添加(和删除)值的正确方法是什么?
您可以通过以下方式更新配料:
(swap! order update :toppings conj "Pepperoni")
我会把toppings
变成一组。我认为您不希望 collection 中有重复的浇头,因此一组是合适的:
(defonce order (r/atom {:first-name "" :last-name "" :toppings #{}})) ; #{} instead of []
然后你仍然可以conj
如另一个答案所述:
(swap! order update :toppings conj "Pepperoni")
但你也可以 disj
:
(swap! order update :toppings disj "Pepperoni")
再解释一下,当您执行 (swap! (:toppings order) ...)
时,您正在从 order
中检索 :toppings
密钥,如果它是一张地图,这将是有意义的,但它一个原子,所以 (:toppings order)
returns nil
.
swap!
的第一个参数应该始终是一个原子(Reagent
原子的工作方式相同)。第二个参数应该是一个函数,它将原子的内容作为它的第一个参数。然后,您可以选择提供更多参数,这些参数将传递给函数参数。
您可以执行以下操作,而不是 minhtuannguyen 的回答:
(swap! order
(fn a [m]
(update m :toppings
(fn b [t]
(conj t "Pepperoni")))))
fn a
接收原子内部的映射,将其绑定到 m
,然后更新它和 returns 一个新映射,成为原子的新值。
如果您愿意,可以重新定义 fn a
以采用第二个参数:
(swap! order
(fn a [m the-key]
(update m the-key
(fn b [t]
(conj t "Pepperoni"))))
:toppings)
:toppings
现在作为第二个参数传递给 fn a
,然后传递给 fn a
内部的 update
。我们可以对 update
的第三个参数做同样的事情:
(swap! order
(fn a [m the-key the-fn]
(update m the-key the-fn))
:toppings
(fn b [t]
(conj t "Pepperoni")))
现在 update
与 fn a
具有相同的签名,因此我们不再需要 fn a
。我们可以直接提供 update
代替 fn a
:
(swap! order update :toppings
(fn b [t]
(conj t "Pepperoni")))
但我们可以继续,因为 update
还接受更多参数,然后将这些参数传递给提供给它的函数。我们可以重写 fn b
以采用另一个参数:
(swap! order update :toppings
(fn b [t the-topping]
(conj t the-topping))
"Pepperoni"))
再一次,conj
与 fn b
具有相同的签名,因此 fn b
是多余的,我们可以使用 conj
代替它:
(swap! order update :toppings conj "Pepperoni")
因此,我们得到了 minhtuannguyen 的答案。
我有一个试剂原子:
(defonce order (r/atom {:firstName "" :lastName "" :toppings [] }))
我想在 :toppings
向量中添加浇头。我尝试了很多变体:
(swap! (:toppings order) conj "Pepperoni")
这给了我:Uncaught Error: No protocol method ISwap.-swap! defined for type null:
(swap! order :toppings "Pepperoni")
有点像,但只是更新顺序,而不是 :toppings
向量。当我取消引用 order
时,我只得到最新的值。
向我的 :toppings
向量添加(和删除)值的正确方法是什么?
您可以通过以下方式更新配料:
(swap! order update :toppings conj "Pepperoni")
我会把toppings
变成一组。我认为您不希望 collection 中有重复的浇头,因此一组是合适的:
(defonce order (r/atom {:first-name "" :last-name "" :toppings #{}})) ; #{} instead of []
然后你仍然可以conj
如另一个答案所述:
(swap! order update :toppings conj "Pepperoni")
但你也可以 disj
:
(swap! order update :toppings disj "Pepperoni")
再解释一下,当您执行 (swap! (:toppings order) ...)
时,您正在从 order
中检索 :toppings
密钥,如果它是一张地图,这将是有意义的,但它一个原子,所以 (:toppings order)
returns nil
.
swap!
的第一个参数应该始终是一个原子(Reagent
原子的工作方式相同)。第二个参数应该是一个函数,它将原子的内容作为它的第一个参数。然后,您可以选择提供更多参数,这些参数将传递给函数参数。
您可以执行以下操作,而不是 minhtuannguyen 的回答:
(swap! order
(fn a [m]
(update m :toppings
(fn b [t]
(conj t "Pepperoni")))))
fn a
接收原子内部的映射,将其绑定到 m
,然后更新它和 returns 一个新映射,成为原子的新值。
如果您愿意,可以重新定义 fn a
以采用第二个参数:
(swap! order
(fn a [m the-key]
(update m the-key
(fn b [t]
(conj t "Pepperoni"))))
:toppings)
:toppings
现在作为第二个参数传递给 fn a
,然后传递给 fn a
内部的 update
。我们可以对 update
的第三个参数做同样的事情:
(swap! order
(fn a [m the-key the-fn]
(update m the-key the-fn))
:toppings
(fn b [t]
(conj t "Pepperoni")))
现在 update
与 fn a
具有相同的签名,因此我们不再需要 fn a
。我们可以直接提供 update
代替 fn a
:
(swap! order update :toppings
(fn b [t]
(conj t "Pepperoni")))
但我们可以继续,因为 update
还接受更多参数,然后将这些参数传递给提供给它的函数。我们可以重写 fn b
以采用另一个参数:
(swap! order update :toppings
(fn b [t the-topping]
(conj t the-topping))
"Pepperoni"))
再一次,conj
与 fn b
具有相同的签名,因此 fn b
是多余的,我们可以使用 conj
代替它:
(swap! order update :toppings conj "Pepperoni")
因此,我们得到了 minhtuannguyen 的答案。