我是Clojure的新手,我有一个嵌套的地图,其结构如下:
{:players
{"p1"
{:id "p1"
:deck []
:hand [{:name "Imp"
:entity-type :card}]
:minions [{:damage-taken 0
:attacks-performed-this-turn 0
:entity-type :minion
:name "Imp"
:id "m1"
:position 0
:owner-id "p1"}]
:hero
{:name "Jaina Proudmoore"
:id "h1"
:entity-type :hero
:mana 0
:damage-taken 0}}
etc
如果我想用一张新地图替换英雄,那张地图的所有键都相同但值不同,我该怎么办?我尝试将更新功能映射到hero的键上,但这没有用。
答案 0 :(得分:2)
有两个常见的函数,当您想更改一个值时,使用ascoc-in;当您要使用函数根据当前值更改值,或想更改多个值时,使用update-in
值:
user> (def players {:players
{"p1"
{:id "p1"
:deck []
:hand [{:name "Imp"
:entity-type :card}]
:minions [{:damage-taken 0
:attacks-performed-this-turn 0
:entity-type :minion
:name "Imp"
:id "m1"
:position 0
:owner-id "p1"}]
:hero
{:name "Jaina Proudmoore"
:id "h1"
:entity-type :hero
:mana 0
:damage-taken 0}}}})
#'user/players
在这种情况下,update-in
是一个很好的选择,因为它使您可以对嵌套集合进行任何操作。这是一个示例,它根据先前的值分配了assoc的一些新值,您也可以添加函数来映射此处的键。
user> (-> (update-in players [:players "p1" :hero]
#(assoc %
:name (str "long lost twin of " (:name %))
:id "h2"
:entity-type :antihero
:mana (inc (:mana %))
:damage-taken (dec (:damage-taken %))))
clojure.pprint/pprint)
{:players
{"p1"
{:id "p1",
:deck [],
:hand [{:name "Imp", :entity-type :card}],
:minions
[{:damage-taken 0,
:attacks-performed-this-turn 0,
:entity-type :minion,
:name "Imp",
:id "m1",
:position 0,
:owner-id "p1"}],
:hero
{:name "long lost twin of Jaina Proudmoore",
:id "h2",
:entity-type :antihero,
:mana 1,
:damage-taken -1}}}}
user>