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

Reply via email to