Hussein,

The previous example (from your other thread) worked, as it happened
to involve removing the parents of nodes which match the predicate -
the make-node function I'd given you worked more or less by accident
in that one specific case, but not here.  Apologies if you lost time
due to my mistake.

To explain what's happening, let's look at the two interesting
functions we pass to clojure.zip/zipper - "children", which is
required to return a seq of a branch's children, and "make-node",
described as "a fn that, given an existing node and a seq of children,
returns a new branch node with the supplied children."   When you do
what amounts to (z/remove {a {b 11 c 12}}), clojure.zip needs some way
to accomplish that, without having a perfect understanding of exactly
how your data is structured.  When combined with the navigation
functions exposed by the library, children & make-node are enough to
get us there.

In this instance, calling z/remove on a grandchild of the root
triggers calls to make-node in order to reconstruct the parent ({b 7 c
8}) of the removed node with a new child seq not containing the node.
And, in turn, needs to be called on the removed node's grandparent
(the root - {children [....]}) -to reconstruct it with a node seq
containing the modified {b 7 c 8} node from the previous step.

The correct make-node implementation (assoc p "children" c) attaches
the sequence of children to the given parent node, in the place we
expect it.

Take care,
Moe

On Thu, Aug 27, 2015 at 1:59 PM, Hussein B. <hubaghd...@gmail.com> wrote:
> Thanks a lot Moe for your help. I always appreciate your patience and
> skills.
>
> Would you explain why your zipper works in this case?
>
> Thanks again.
>
> On Thursday, August 27, 2015 at 12:11:14 PM UTC+2, Moe Aboulkheir wrote:
>>
>> Hussein,
>>
>> Making this change to the zipper definition:
>>
>> (z/zipper #(get % "children") #(get % "children") (fn [p c] (assoc p
>> "children" c)) {"children" z})
>>
>> looks like it'll do the right thing here.
>>
>> Take care,
>> Moe
>>
>> On Thu, Aug 27, 2015 at 11:03 AM, Hussein B. <hubag...@gmail.com> wrote:
>> > The modify function
>> >
>> > (defn modify [loc]
>> >  (-> loc z/remove))
>> >
>> >
>> > On Thursday, August 27, 2015 at 11:58:31 AM UTC+2, Hussein B. wrote:
>> >>
>> >> Hi,
>> >>
>> >> I'm trying to remove an element from nested data structure (nesting in
>> >> unknown, so I'm trying to come up with a generic solution:
>> >>
>> >>  (def z [
>> >>           {"a" {"b" 1 "c" 2}
>> >>            "children" [{"a" {"b" 3 "c" 4}
>> >>                         "children" []}]}
>> >>           {"a" {"b" 5 "c" 6}
>> >>            "children" []}
>> >>           {"a" {"b" 7 "c" 8}
>> >>            "children" [{"a" {"b" 9 "c" 10}
>> >>                         "children" []}
>> >>                        {"a" {"b" 11 "c" 12}
>> >>                         "children" [{"a" {"b" 13 "c" 14} "children" []}
>> >> {"a" {"b" 15 "c" 16} "children" []}]}]}])
>> >>
>> >>
>> >>
>> >>
>> >> (def loz (z/zipper #(get % "children") #(get % "children") (fn [_ x ]
>> >> x)
>> >> {"children" z}))
>> >>
>> >>
>> >>
>> >> (defn to-change? [loc]
>> >>  (if (= 11 (get-in (z/node loc) ["a" "b"]))
>> >>  true
>> >>  false))
>> >>
>> >>
>> >> (loop [loc loz]
>> >>     (if (z/end? loc)
>> >>       (z/root loc)
>> >>       (recur (z/next
>> >>           (cond (to-change? loc)
>> >>                 (modify loc)
>> >>                 :else loc)))))
>> >>
>> >>
>> >> That gives a very wrong output:
>> >>
>> >> ({"a" {"b" 1, "c" 2}, "children" [{"a" {"b" 3, "c" 4}, "children" []}]}
>> >> {"a" {"b" 5, "c" 6}, "children" []} ({"a" {"b" 9, "c" 10}, "children"
>> >> []}))
>> >>
>> >>
>> >>
>> >> Parent {"a" {"b" 7 "c" 8} is getting deleted which is wrong.
>> >>
>> >> What I'm doing wrong?
>> >>
>> >> Thanks for help and time.
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups "Clojure" group.
>> > To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
>> > For more options, visit https://groups.google.com/d/optout.
>
> --
> 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.

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

Reply via email to