改变存储在雾化地图中的矢量的惯用方法是什么?

时间:2016-01-18 01:19:50

标签: clojure clojurescript

我有一个名为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 %))

但这似乎不起作用。

非常感谢任何帮助!

4 个答案:

答案 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"})