dictionary - 如何使用 clojure 中的函数替换嵌套映射中的多个值?

标签 dictionary clojure immutability

我是 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

如果我想用一张新 map 替换英雄,一张具有所有相同键但不同值的 map ,我该怎么做?我尝试将更新功能映射到英雄的按键上,但这没有用。

最佳答案

有两个常见的函数可以实现这一点,assoc-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> 

关于dictionary - 如何使用 clojure 中的函数替换嵌套映射中的多个值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53211714/

相关文章:

dart - Flutter:无状态小部件中的可变字段

ios - Swift:创建字典值数组

c# - 无法将 keyValuePair 直接添加到 Dictionary

recursion - Clojure循环/递归

java - 类的实例是不可变的吗?

reactjs - React,是否绝对有必要将 React 状态视为不可变?

html - 如何在 SVG 文件中查找相邻路径?

c++ - 对 pair 和 double 的映射进行排序

Clojure 深度合并忽略 nil 值

clojure - Hiccup 中的条件句,我可以让这个更惯用吗?