On Aug 16, 12:02 pm, botgerry <botge...@gmail.com> wrote:
> Hello,all
>
> I'm new to functional programming,want to know how to address nested
> inner seqs in clojure
>
> (def a [[1 2 3 4] [ "ok" "metoo"] [ 5 8 9 ]])
>
> 1:  searching in a, if find one inner vector includes number 9 then
> append it a number 13
>  [[1 2 3 4] [ "ok" "metoo"] [ 5 8 9 ]]  => [[1 2 3 4] [ "ok" "metoo"]
> [ 5 8 9 13]]
>
> 2: searching in a, if found two or many inner vectors include same
> element the merge them as one inner vector
> others not touch
>
> (def b ( conj  a  [ 5  10 "oops"]))  => [[1 2 3 4] ["ok" "metoo"] [5 8
> 9] [5 10 "oops"]]
> in b, [5 8 9] and [5 10 "oops"] both include 5, it should be merge to
> [5 8 9 10 "oops"] :
> [[1 2 3 4] ["ok" "metoo"] [5 8 9] [5 10 "oops"]]  => [[1 2 3 4] ["ok"
> "metoo"] [5 8 9 10 "oops"]]
>
> I only found one solution to question 1 using zipper :
> (def dz (zip/vector-zip a))
> (defn append-to-blocks [x y] ;lookup x in blocks,if found then add y
> to inner block
>    (loop [loc dz]            ;dz is blocks
>      (if (zip/end? loc)
>        (zip/root loc)
>        (recur
>         (zip/next
>          (if (and (vector? (zip/node loc)) (includes? (zip/node loc) x))
>            (let [new-coll (conj (zip/node loc) y)]
>            (zip/replace loc new-coll))
>            loc))))))
>
> user=> (append-to-blocks 9 13)
> [[1 2 3 4] ["ok" "metoo"] [5 8 9 13]]

I think using a zipper is a good solution

> but still not figure out one way to question 2, i have tried:
> (defn merge-inner-blocks [x blocks] ;x is element maybe in many inner
> blocks
>   (let [with-out-x (for [b blocks :when (not (includes? b x))] b)
>         with-x (for [b blocks :when (includes? b x)] b)]
>     (def blocks (concat with-out-x (vector (flatten with-x))))))   ;
> just merge them, not remove the same element

You should never use def inside a function. It's a certain sign that
you're doing something wrong. Why don't you just return the result
normally?

That said, I can't think of a fast solution for this either; but you
can wrap the (concat ...) in (vec (set ...)) to get a vector of
uniques.

> (merge-inner-blocks 5 b)
> #'user/blocks
> user=> blocks
> ([1 2 3 4] ["ok" "metoo"] (5 8 9 5 10 "oops"))  ; here how to remove
> one of the "5"?  vector has changed to list?
>
> 3, I also found my solutions to this alike problems are not
> concise,and a bit ugly, any libs or appropriate way to process inner
> nested seqs in clojure? i thought those ops maybe frequently
> encountered in practical programming

I have to say I haven't had the need to do much with nested seqs, but
I suppose for that purpose clojure.zip would be worth learning more in
depth. It is designed for traversing and "editing" data structures,
after all.

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