向右跳,更好的方法:
(assoc-in
{:children [{:children [{:children [{:children [{:children []}]}]}]}]}
[:children 0 :children 0 :children 0 :children 0 :children 0]
:hello)
我想将:hello
插入最深的:children
向量中。上面我正在使用assoc-in
。
有没有比assoc-in
更好的方法?
或者,如果{/ 1}}是唯一的方法, if ,您将如何处理assoc-in
的第二个参数assoc-in
?
也很好知道是否有一些东西也适用于插入[k & ks]
和任意:world
的矢量......就像第三个孩子或第二个孩子一样第一个孩子。
答案 0 :(得分:5)
assoc-in
的向量参数不必是文字,因此您可以根据需要构建它。
(def nested-map
{:children [{:children [{:children [{:children [{:children []}]}]}]}]})
(assoc-in nested-map (vec (take 10 (cycle [:children 0]))) :hello)
;=> {:children [{:children [{:children [{:children [{:children [:hello]}]}]}]}]}
或者对于第1个孩子的第2个孩子的第3个孩子,构建像
这样的路径(vec (interleave (repeat :children) [0 1 2]))
;=> [:children 0 :children 1 :children 2]
更一般地说,您可以使用zippers随意移动嵌套地图,例如下一个孩子。运动功能可以组成等。
(require '[clojure.zip :as zip])
(def z (zip/zipper map? :children #(assoc % :children (vec %2)) nested-map))
(-> (ffirst (filter (comp zip/end? second) ; find last
(partition 2 1 (iterate zip/next z))))
(zip/edit (constantly :hello)) ; change to :hello
zip/root) ; bubble up changes
;=> {:children [{:children [{:children [{:children [{:children [:hello]}]}]}]}]}
答案 1 :(得分:2)
您也可以将clojure.walk
用于此
(require '[clojure.walk :as w])
(def nested-map
{:children [{:children [{:children [{:children [{:children []}]}]}]}]})
(w/postwalk (fn [node] (if (and (vector? node) (empty? node))
(conj node :hello)
node))
nested-map)
=> {:children [{:children [{:children [{:children [{:children [:hello]}]}]}]}]}