Dictionary 在中使用assoc永久更改映射Clojure中的值

Dictionary 在中使用assoc永久更改映射Clojure中的值,dictionary,clojure,Dictionary,Clojure,很抱歉问了这么多问题 我有一张卡片地图: (def cards { :card1 {:name "Wisp" :type "Monster" :damage 1 :health 1 :cost 0 :ability 0 :active true} :card2 {:name "Spider Tank" :type "Monster" :damage 3 :health 4 :cost 3 :

很抱歉问了这么多问题

我有一张卡片地图:

    (def cards
  {
    :card1 {:name "Wisp"              :type "Monster"     :damage 1   :health 1   :cost 0   :ability 0 :active true}
    :card2 {:name "Spider Tank"       :type "Monster"     :damage 3   :health 4   :cost 3   :ability 0 :active true}
    :card3 {:name "Boulder Fist Ogre" :type "Monster"     :damage 6   :health 7   :cost 6   :ability 0 :active true}
    :card4 {:name "Bloodfen Raptor"   :type "Monster"     :damage 3   :health 2   :cost 2   :ability 0 :active true}
    :card5 {:name "Chillwind Yeti"    :type "Monster"     :damage 4   :health 5   :cost 4   :ability 0 :active true}
    :card6 {:name "Magma Rager"       :type "Monster"     :damage 5   :health 1   :cost 3   :ability 0 :active true}
    :card7 {:name "War Golem"         :type "Monster"     :damage 7   :health 7   :cost 7   :ability 0 :active true}
    :card8 {:name "Oasis Snapjaw"     :type "Monster"     :damage 2   :health 7   :cost 4   :ability 0 :active true}
    :card9 {:name "River Crocolisk"   :type "Monster"     :damage 2   :health 3   :cost 2   :ability 0 :active true}
    :card10 {:name "Murloc Raider"    :type "Monster"     :damage 2   :health 1   :cost 1   :ability 0 :active true}
    :card11 {:name "Northshire Cleric":type "Monster"     :damage 1   :health 3   :cost 1   :ability 2 :active true}
    :card12 {:name "Nat Peagle"       :type "Monster"     :damage 0   :health 4   :cost 2   :ability 4 :active true}
    :card13 {:name "Molten Giant"     :type "Monster"     :damage 8   :health 8   :cost 20  :ability 0 :active true}
    }
 )
这些卡片在组成我的董事会的列表中:

(def board1 (list (:card3 cards) (:card4 cards) (:card11 cards) nil nil nil nil))
我要做的是将卡上的活动标志从true更改为false

我知道我可以通过以下方式直接对我的卡片收藏进行此操作:

user=> (assoc-in (:card11 cards) [:active] false)
{:ability 2, :name "Northshire Cleric", :type "Monster", :damage 1, :active false, :health 3, :cost 1}
我正在尝试构建一个函数,当给它一个集合(板)和一个数字(n)卡时。使此板中的此卡永久为假

我一直在尝试原子,但到目前为止没有任何乐趣

(test-function board1 1)

(defn test-function [coll number]
  (let [test (atom coll)]
    (swap! test assoc-in (get (nth @test number)) [:active] false)
    (println test)))

我想知道我做错了什么,是否有更干净的方法不用原子就能做到这一点

您需要在
let
块之外声明atom。按照您拥有它的方式,您每次都在重新绑定它。
atom
对于有状态的东西是一个很好的选择,所以像这样声明atom:

(def cards (atom
  {:card1 {:name "Wisp" :active true}
   :card2 {:name "Spider Tank" :active true}}))
然后,您可以编写函数以在
false
中交换,如下所示:

(defn myfunc [coll number]
  (swap! coll assoc-in [(str :card number) :active] false ))

您不需要两个不同的函数,一个用于设置为
true
,另一个用于设置为
false
。您应该在下一步执行此操作,并使其读取当前布尔值,然后在中关联相反的值。(还请注意,我将样本数据样本保持得非常小)。;)

您需要在
let
块之外声明atom。按照您拥有它的方式,您每次都在重新绑定它。
atom
对于有状态的东西是一个很好的选择,所以像这样声明atom:

(def cards (atom
  {:card1 {:name "Wisp" :active true}
   :card2 {:name "Spider Tank" :active true}}))
然后,您可以编写函数以在
false
中交换,如下所示:

(defn myfunc [coll number]
  (swap! coll assoc-in [(str :card number) :active] false ))
您不需要两个不同的函数,一个用于设置为
true
,另一个用于设置为
false
。您应该在下一步执行此操作,并使其读取当前布尔值,然后在中关联相反的值。(还请注意,我将样本数据样本保持得非常小)。;)

JT93

根据您的评论,您希望取消atom,并采用干净的更新方法

如果你能在你的问题中用更多的信息来阐明你所说的永久性是什么意思。例如:是否要在执行的整个生命周期内保持卡的板状态?如果是这样,您可能需要使用
atom
,尽管Clojure还有一些不同的方法

首先,考虑将<代码> BoARD1<代码>定义为向量而不是列表。然后,您就可以不用复杂的逻辑,只需在中使用

assoc,而只需大张旗鼓:

(def board1 [(:card3 cards) (:card4 cards) (:card11 cards) nil nil nil nil])

(defn test-function [coll number]
    (assoc-in coll [number :active] false))

(clojure.pprint/pprint (test-function board1 0))
JT93

根据您的评论,您希望取消atom,并采用干净的更新方法

如果你能在你的问题中用更多的信息来阐明你所说的永久性是什么意思。例如:是否要在执行的整个生命周期内保持卡的板状态?如果是这样,您可能需要使用
atom
,尽管Clojure还有一些不同的方法

首先,考虑将<代码> BoARD1<代码>定义为向量而不是列表。然后,您就可以不用复杂的逻辑,只需在

中使用
assoc,而只需大张旗鼓:

(def board1 [(:card3 cards) (:card4 cards) (:card11 cards) nil nil nil nil])

(defn test-function [coll number]
    (assoc-in coll [number :active] false))

(clojure.pprint/pprint (test-function board1 0))

你说的“永久”是什么意思?另外,您应该使用布尔
true
false
而不是
f
t
字符串。我将更改为true和false。从我的理解来看,当我把“真”改为“假”时,它不会一直是假的。如果可能的话,我希望它在函数期间保持为真或假。@JT93“更改”是什么意思?这里“永久”是什么意思?另外,您应该使用布尔
true
false
而不是
f
t
字符串。我将更改为true和false。从我的理解来看,当我把“真”改为“假”时,它不会一直是假的。如果可能的话,我希望在函数执行期间保持为真或假。@JT93“更改”是什么意思?
updatein
with
not
似乎是更好的方法。卡片在列表中,数字是列表中的索引,如原问题所示。如图所示,创建一个字符串将直接在地图上工作,但不会在列表上工作。
使用
not
中更新似乎是完成最后一个字符串的更好方法。根据原始问题,卡片位于列表中,数字是列表中的索引。如图所示,创建字符串将直接在地图上工作,但不会在列表上工作。