Как заменить несколько значений во вложенной карте, используя функцию в clojure? - PullRequest
0 голосов
/ 08 ноября 2018

Я новичок в 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

Если бы я хотел заменить героя новой картой, с одинаковыми ключами, но разными значениями, как я мог бы это сделать? Я пытался отобразить функцию обновления на клавиши героя, но это не сработало.

1 Ответ

0 голосов
/ 08 ноября 2018

для этого есть две общие функции, связанные, когда вы хотите изменить одно значение, и 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 - хорошее совпадение, потому что оно позволяет вам делать все, что вы хотите с вложенной коллекцией. Вот пример, который связывает некоторые новые значения, основанные на предыдущих, вы также можете добавить свою функцию для сопоставления здесь ключей.

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> 
...