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

我是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"}]}},
   {: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,它还关联嵌套关联结构中的值。 希望这有帮助