Clojure 克罗朱尔。更新双嵌套值
我是Clojure的新手,一切都是新的,但也很有趣。所以我有这些数据:Clojure 克罗朱尔。更新双嵌套值,clojure,clojurescript,Clojure,Clojurescript,我是Clojure的新手,一切都是新的,但也很有趣。所以我有这些数据: {:test {:title "Some Title"}, :questions [ {:id 1, :full-question {:question "Foo question", :id 1, :answers [{:id 7, :question_id 1, :answer "Foobar answer"}, {:id 8, :question_id 1, :answer "Foobar answer two
{:test {:title "Some Title"}, :questions [
{:id 1, :full-question {:question "Foo question", :id 1, :answers [{:id 7, :question_id 1, :answer "Foobar answer"}, {:id 8, :question_id 1, :answer "Foobar answer two"}]}},
{:id 5, :full-question {:question "Foo question", :id 5, :answers [{:id 12, :question_id 5, :answer "Foobar answer"}]}},
{:id 9, :full-question {:question "Foo question", :id 9, :answers [{:id 14, :question_id 9, :answer "Foobar answer"}, {:id 20, :question_id 9, :answer "Foobar answer two"}]}}
]}
一个经典的测试->问题->答案类型的数据结构。我有一个新信息:
(def new-answer {:id 33, :answer "Another foobar answer", :question-id 9 })
我需要更新第一个结构,将新答案添加到:问题向量中:id编号9的答案中
我尝试使用update in函数,但我不知道该告诉通讯员什么:两个向量内的映射中的id。我的意思是,我不知道如何构建我想要进行更改的路径。您对更新的想法是正确的。您可以首先计算问题向量中的索引,然后创建路径:问题、问题索引、:完整问题、:答案。然后你可以在你的新答案中加入: def数据{…} 按id定义索引 [v id] 第一个筛选器=:id v%id范围计数v defn添加答案 [答复] let[q-索引id索引:问题数据:问题id答案] 更新数据[:问题q-索引:完整问题:答案] 联合回答
你对更新有正确的想法。您可以首先计算问题向量中的索引,然后创建路径:问题、问题索引、:完整问题、:答案。然后你可以在你的新答案中加入: def数据{…} 按id定义索引 [v id] 第一个筛选器=:id v%id范围计数v defn添加答案 [答复] let[q-索引id索引:问题数据:问题id答案] 更新数据[:问题q-索引:完整问题:答案] 联合回答
此外,还有一个很好的库用于这种结构编辑,称为 你的案子可以这样解决:
(require '[com.rpl.specter :refer [ALL AFTER-ELEM setval]])
(defn add-answer [data {question-id :question-id :as new-answer}]
(setval [:questions ALL #(== question-id (:id %)) :full-question :answers AFTER-ELEM]
new-answer data))
user> (add-answer data {:id 33, :answer "Another foobar answer", :question-id 9 })
;;=> {:test {:title "Some Title"},
;; :questions
;; [
;; ;; ... all other ids
;; {:id 9,
;; :full-question
;; {:question "Foo question",
;; :id 9,
;; :answers
;; [{:id 14, :question_id 9, :answer "Foobar answer"}
;; {:id 20, :question_id 9, :answer "Foobar answer two"}
;; {:id 33, :answer "Another foobar answer", :question-id 9}]}}]}
此外,还有一个很好的库用于这种结构编辑,称为 你的案子可以这样解决:
(require '[com.rpl.specter :refer [ALL AFTER-ELEM setval]])
(defn add-answer [data {question-id :question-id :as new-answer}]
(setval [:questions ALL #(== question-id (:id %)) :full-question :answers AFTER-ELEM]
new-answer data))
user> (add-answer data {:id 33, :answer "Another foobar answer", :question-id 9 })
;;=> {:test {:title "Some Title"},
;; :questions
;; [
;; ;; ... all other ids
;; {:id 9,
;; :full-question
;; {:question "Foo question",
;; :id 9,
;; :answers
;; [{:id 14, :question_id 9, :answer "Foobar answer"}
;; {:id 20, :question_id 9, :answer "Foobar answer two"}
;; {:id 33, :answer "Another foobar answer", :question-id 9}]}}]}
使用clojure,可以找到updatein函数和assoc函数。您可以使用Alex建议的代码在中进行更新。assoc相当相似 定义更改[ma a-map id] 助理:问题ma if let[xq first filter int?映射索引fn[idx mp]if=:id mp id idx nil:ma] xq 马伯爵公司 a图 您可以根据需要更新地图 更改o-map n-map idx;;参数-1是要更改的映射, ;;param-2是新的答案, ;;idx是要更改的:id。 您还可以在find中引用assoc,它还关联嵌套关联结构中的值。
希望这能有所帮助。使用clojure,您可以在函数中找到update,并找到assoc。您可以使用Alex建议的代码在中进行更新。assoc相当相似 定义更改[ma a-map id] 助理:问题ma if let[xq first filter int?映射索引fn[idx mp]if=:id mp id idx nil:ma] xq 马伯爵公司 a图 您可以根据需要更新地图 更改o-map n-map idx;;参数-1是要更改的映射, ;;param-2是新的答案, ;;idx是要更改的:id。 您还可以在find中引用assoc,它还关联嵌套关联结构中的值。 希望这有帮助