Paul_B_Hansen <[email protected]> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en