clojure - 使用交换!在嵌套地图上
问题描述
我正在关注 Professional Clojure 一书的第 6 章。
App状态目前定义如下:
(defonce app-state
(reagent/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}}}}}))
我需要使用swap!
添加一个新的键值来表示一个新的故事,由一个具有给定字段值的 id 键控。
(defn add-story! [app-state project-id title status] ;
; Q. How to use swap! to add a key value pair into :stories?
(swap! app-state update [:projects project-id :stories] assoc <- INCORRECT CODE HERE
(unique) {:title title
:status status
:order (inc (max-order app-state project-id))}))
此处未显示的唯一函数只会生成任何唯一的 uuid。max-order 函数得到了最大的顺序。我不得不修改它,因为本书章节的内容与提供的实际最终代码不一致。这是我的最大订单版本:
(defn max-order [app-state project-id]
(apply max 0 (map :order (vals (get-in @app-state [:projects project-id :stories])))))
问题:如何使用swap!
向其中添加新的键值:stories
?
我曾经尝试过,但它现在打败了我。
我确实觉得这个嵌套地图不是最好的表示 - 在作为下载提供的最终代码中,作者已更改为更具关系型的模型,项目和故事都作为顶级实体,故事包含 project_id,但是swap!
在继续之前解决这个第一次使用会很好。
解决方案
我认为您可以assoc-in
在这种情况下使用它,它比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"}}}}}
推荐阅读
- html - 更改 HTML 时播放()不起作用
- laravel - 无法在 Eloquent 模型上访问 id
- sql - SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; “=”附近的语法不正确
- acumatica - 使用 onclosingpop 关闭弹出窗口时执行函数
- java - jGRASP appletviewer 不工作(路径错误)
- c++ - 如何禁用 MPI 的 C++ 包装器?
- graphdb - 在 ontext graphdb 中删除 lucene 索引
- elasticsearch - ElasticSearch:在包含文档的日期范围中查找不同日期的最佳方法是什么?
- kendo-ui - kendo-ui angular 6 如何使用模板自定义网格的列
- azure-devops - 如何为 repo 的 wiki 创建构建管道?