On Tuesday, May 6, 2014 4:07:11 PM UTC+1, Alex Miller wrote: > > I wrote this article long ago which hints about this at the end: > https://www.ibm.com/developerworks/library/j-treevisit/ >
I started from that actually, very helpful article. I have since noticed a bug in my previous skip function where it would loop infinitely when skipping from the rightmost location. The fix includes an end function, so I can no just iterate backwards using that as you suggested. Leaving this here for future reference, in case anybody comes across the same problem: (defn end "returns the location loc where (end? (next loc)) is true." [loc] (loop [loc loc] (let [loc (z/rightmost loc)] (if (z/branch? loc) (recur (z/down loc)) loc)))) (defn skip "returns the next location that is not a child of this one" [start-loc] (loop [loc start-loc] (cond ; can't skip, jump to end (nil? loc) (z/next (end start-loc)) ; at end (z/end? loc) loc ; go to right/up true (or (z/right loc) (recur (z/up loc)))))) > > The approach I have taken for editing trees with zippers is to do a > post-walk from end to beginning - that way you're always done transforming > and will not walk into your edited subtrees. The article does talk a little > about how to separate navigation from transformation; it's not particularly > hard. You want to start from your rightmost node, which you can get from a > repeated application of zip/rightmost or last of zip/rights. Then > repeatedly call prev till you reach a node without a parent at that point > convert the loc to a node in the termination. > > I can dig up actual code for this later if you're interested. > > Alex > > > On Monday, May 5, 2014 6:01:04 PM UTC-5, Pascal Germroth wrote: >> >> Hi, >> >> I'm using clojure.zip to edit a tree by visiting each location using >> zip/next, possibly using zip/replace to alter the tree. >> There are cases where I replace a part of the tree with another tree that >> will/must not be visited, but I couldn't find a good way to skip nodes, >> since >> (zip/next (zip/replace loc new-subtree)) will walk right into my new >> tree, and I can't use (zip/right (zip/replace loc new-subtree)) as the >> replaced location might already be the rightmost. >> >> Is there a built-in function I missed, or a zip enhancement library I >> could use? >> >> (defn skip >> "returns the next location that is not a child of this one" >> [loc] >> (if (or (z/end? loc) (nil? loc)) >> loc >> (loop [loc loc] >> (or (z/right loc) >> (recur (z/up loc)))))) >> >> I came up with this replacement, does that seem like a good idea, or am I >> using zip completely wrong (because what I really would like to do is >> iterate backwards through the tree, starting at the end, using zip/prev; >> but there's also no function to just jump to the end as far as I can tell) >> >> >> Cheers, >> >> -- >> pascal >> > -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.