Clojure 使用交换!在嵌套地图上

Clojure 使用交换!在嵌套地图上,clojure,Clojure,我将遵循《专业Clojure》一书的第6章 应用程序状态当前定义如下: (defonce应用程序状态 (试剂/原子) {:项目 {“aaa” {:标题“构建鞭” :故事 {1{:标题“为项目和故事设计数据模型” :状态“完成” :顺序1} 2{:title“创建故事标题输入表单” :顺序2} 3{:标题“实现完成故事的方法” :订单号(3}}) 我需要使用交换添加一个新的键值来表示一个新的故事,由一个id键入给定字段的值 (defn添加故事![app state project id titl

我将遵循《专业Clojure》一书的第6章

应用程序状态当前定义如下:

(defonce应用程序状态
(试剂/原子)
{:项目
{“aaa”
{:标题“构建鞭”
:故事
{1{:标题“为项目和故事设计数据模型”
:状态“完成”
:顺序1}
2{:title“创建故事标题输入表单”
:顺序2}
3{:标题“实现完成故事的方法”
:订单号(3}})
我需要使用
交换
添加一个新的键值来表示一个新的故事,由一个id键入给定字段的值

(defn添加故事![app state project id title status];
;Q.如何使用swap!将键值对添加到:故事中?
(swap!应用程序状态更新[:projects project id:stories]assoc请务必每天学习!还有更多

我想你只需要在

(ns tst.demo.core
  (:use tupelo.core tupelo.test)
  (:require
    [clojure.string :as str]
    ))

(def state
  {:projects
   {"aaa"
    {:title   "Build Whip"
     :stories {1 {:title  "Design a data model for projects and stories"
                  :status "done"
                  :order  1}
               2 {:title "Create a story title entry form"
                  :order 2}
               3 {:title "Implement a way to finish stories"
                  :order 3}}}}})

(dotest
  (let [result (update-in state [:projects "aaa" :stories]
                 assoc 99 {:title  "Agent 99"
                           :status "foxy"
                           :order  "some-order-stuff"})
        ]
    (spyx-pretty result)))
结果:

-------------------------------
   Clojure 1.10.1    Java 13
-------------------------------

Testing tst.demo.core
result => 
{:projects
 {"aaa"
  {:title "Build Whip",
   :stories
   {1
    {:title "Design a data model for projects and stories",
     :status "done",
     :order 1},
    2   {:title "Create a story title entry form", :order 2},
    3   {:title "Implement a way to finish stories", :order 3},
    99  {:title "Agent 99", :status "foxy", :order "some-order-stuff"}}}}}
当数据位于原子内部时,解决方案几乎相同:

  (def state-atom (atom state))
  (let [result (swap! state-atom update-in [:projects "aaa" :stories]
                 assoc 99 {:title  "Agent 99"
                           :status "foxy"
                           :order  "some-order-stuff"})]
    (spyx-pretty @state-atom))
结果

(clojure.core/deref state-atom) => 
{:projects
 {"aaa"
  {:title "Build Whip",
   :stories
   {1
    {:title "Design a data model for projects and stories",
     :status "done",
     :order 1},
    2 {:title "Create a story title entry form", :order 2},
    3 {:title "Implement a way to finish stories", :order 3},
    99
    {:title "Agent 99", :status "foxy", :order "some-order-stuff"}}}}}

我认为您可以在本例中使用
assoc,这比
update in
简单一点,更好地描述您试图实现的目标:

(def app-state
  (atom 
   {:projects
    {"aaa"
     {:title   "Build Whip"
      :stories {1 {:title  "Design a data model for projects and stories"
                   :status "done"
                   :order  1}
                2 {:title "Create a story title entry form"
                   :order 2}
                3 {:title "Implement a way to finish stories"
                   :order 3}}}}}))

(defn unique [] (rand-int 1000000000))

(let [unique-key (unique)]
  (swap! app-state
         assoc-in
         [:projects "aaa" :stories unique-key]
         {:title  (str "Agent " unique-key)
          :status "foxy"
          :order  "some-order-stuff"}))
@app-state
;; => {:projects
;;     {"aaa"
;;      {:title "Build Whip",
;;       :stories
;;       {1 {:title "Design a data model for projects and stories", :status "done", :order 1},
;;        2 {:title "Create a story title entry form", :order 2},
;;        3 {:title "Implement a way to finish stories", :order 3},
;;        295226401 {:title "Agent 295226401", :status "foxy", :order "some-order-stuff"}}}}}


有一个输入错误,
update
实际上应该是
updatein