Paul_B_Hansen <paul.b.han...@gmail.com> writes: > I tried to simply get a zipper working for nested > maps but I didn't succeed. My attempt is below: > > (defn map-zip [root] > (zip/zipper map? > seq > (fn [node children] (with-meta (hash-map children) (meta > node))) > root))
So the problem with that approach is that maps contain keys and values. If you use "seq" as the children function then your children look like: [:some-key {...}] so when you call map? on them the answer is always going to be false. So the first question is what is a node? Since a map is associative a node must consist of a key and a value. The value could be another map, in which case it is a branch node, or something else like an integer or a string in which case its a leaf node. This suggests that our branch test should be #(map? (val %)) and our children function should be #(seq (val %)). Now how do we add some children to a nod? We take the existing key and replace the value with a new map that has more children. Finally, so that the root of the zipper is also a node we need to give a key to it, perhaps :root or something. So putting it all together we have: (defn map-zip [m] (zip/zipper #(map? (second %)) #(seq (second %)) (fn [node children] [(first node) (into {} children)]) [:root m])) (defn val-editor [f] (fn [entry] [(first entry) (f (second entry))])) (-> (map-zip {:foo {:bar {:baz 2}}}) zip/down zip/down (zip/insert-right [:greeting "Hello!"]) zip/down (zip/edit (val-editor inc)) zip/root) ;; => [:root {:foo {:greeting "Hello!", :bar {:baz 3}}}] -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en