我有一个名为app-state
的原子来保存地图。它看起来像这样:
{:skills [{:id 1 :text "hi"} {:id 2 :text "yeah"}]}
使用:id = 2
删除向量中元素的惯用方法是什么?结果如下:
{:skills [{:id 1 :text "hi"}]}
... 到目前为止,我有这个:
(defn new-list [id]
(remove #(= id (:id %)) (get @app-state :skills)))
swap! app-state assoc :skills (new-list 2)
它有效,但我觉得这不太对。我想它可能是这样的:
swap! app-state update-in [:skills] remove #(= id (:id %))
但这似乎不起作用。
非常感谢任何帮助!
答案 0 :(得分:2)
试试这个:
(defn new-list [app-state-map id]
(assoc app-state-map :skills (into [] (remove #(= id (:id %)) (:skills app-state-map)))))
(swap! app-state new-list 2)
swap!
会将atom的当前值传递给您提供的函数。没有必要在函数中自行取消引用它。
有关详细信息,请参阅swap!
上的docs。
答案 1 :(得分:1)
(swap! state update :skills (partial remove (comp #{2} :id)))
答案 2 :(得分:0)
(def skills {:skills [{:id 1 :text "hi"} {:id 2 :text "yeah"}]})
(defn remove-skill [id]
(update skills :skills (fn [sks] (vec (remove #(= id (:id %)) sks)))))
然后你就可以打电话给(remove-skill 1)
并看到只留下另一个(技能:id为2)。
我更喜欢你的方式。这需要适应原子的使用。
答案 3 :(得分:0)
您可以使用filter
执行此操作。这是一个带有id和地图的函数,让你过滤掉任何与你的标准不符的东西。当然,您可以根据需要使#()
阅读器宏检查是否存在平等而不是不平等。
user=> (def foo {:skills [{:id 1 :text "hi"} {:id 2 :text "yeah"}]})
#'user/foo
user=> (defn bar [id sklz] (filter #(not= (:id %) id) (:skills sklz)))
#'user/bar
user=> (bar 1 foo)
({:id 2, :text "yeah"})
user=> (bar 2 foo)
({:id 1, :text "hi"})