Meikel Brandmeyer <m...@kotka.de> writes:

> Hi,
>
> On Aug 21, 12:05 pm, Jan Rychter <j...@rychter.com> wrote:
>
>> It isn't what I want. But that's because I misspecified what I actually
>> wanted. I didn't think about the problem enough. I need something more
>> akin to a splice function:
>>
>> (splice tree1 index tree2)
>>
>> (splice '(1 2 (3 4 5) 6) 4 '(7 8 (9 10)))
>> should produce => '(1 2 (3 7 8 (9 10) 6))
>
>         (defn zip-splice
>           [loc node new-node]
>           (loop [loc loc]
>             (cond
>               (zip/end? loc)
>               (throw (Exception. "Node not found"))
>
>               (= (zip/node loc) node)
>               (let [childs (zip/children new-node)
>                     loc    (reduce #(zip/insert-left %1 %2) loc
> childs)]
>                 (zip/remove loc))
>
>               :else (recur (zip/next loc)))))
>
> user=> (def z (zip/vector-zip [1 2 [3 4 5] 6]))
> #'user/z
> user=> (def s (zip/vector-zip [7 8 [9 10]]))
> #'user/s
> user=> (zip/root (zip-splice z 4 s))
> [1 2 [3 7 8 [9 10] 5] 6]
>
> Be aware of the '=' there. This you might want to replace with some
> smarter function to check for the identity of a node. I stumpled over
> that in this thread: 
> http://groups.google.com/group/clojure/browse_thread/thread/bfd6539ec367a95b
> I'm not really a tree expert. So if you have solved this problem,
> please let me know. I'm still interested in this.

Thanks -- this is good stuff. I appreciate the help.

I meant the "index" as a numeric index into the tree (depth-first
traversal), unrelated to the actual tree contents -- I used natural
numbers in the tree only as an example. My real trees contain mostly
symbols. So your function isn't applicable to my stuff.

In the meantime, I came up with this (nothing like a piece of paper and
some thinking to work things out):

(defn zip-splice [zipped-tree index loc2]
  (let [splice-site (goto-node zipped-tree index)]
    (zip/root
     (zip/replace (zip/up splice-site)
                  (concat (zip/lefts splice-site)
                          (list (zip/node loc2))
                          (zip/rights loc2))))))

where goto-node is defined as:

(defn goto-node [zipped-code n]
  (loop [counter 0
         loc (zip/next zipped-code)]
    (if (or (= counter n) (zip/end? loc))
      loc
      (recur (inc counter) (zip/next loc)))))

This seems to do exactly what I wanted.

--J.

--~--~---------~--~----~------------~-------~--~----~
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