I took a crack at it. Whenever I think of building up a structure, I
think of reduce or into. Like Meikel, I create a nested, sorted-map
tree first, then convert to the vector-of-maps format you describe.

(defn add-path [root path]
  (let [add-child (fn [parent child-path]
                    (if (get-in parent child-path)
                      parent
                      (assoc-in parent child-path
                                {:data (peek child-path)
                                 :children (sorted-map)})))
        ancestor-paths (for [i (range 1 (inc (count path)))]
                         (vec (interpose :children (take i path))))]
    (reduce add-child root ancestor-paths)))

(defn rows->tree [rows]
  {:data :root
   :children (reduce add-path (sorted-map) rows)})

;; Note: consumes stack space
(defn tree-map->vec [node]
  (vec
   (for [[k v] node]
     (if (zero? (count (:children v)))
       (dissoc v :children)
       (assoc v :children (tree-map->vec (:children v)))))))

;; Example

(def data1 [[:a1 :b1 :c1]
            [:a1 :b1 :c2]
            [:a1 :b2 :c3]
            [:a1 :b2 :c4]
            [:a2 :b3 :c5]
            [:a2 :b3 :c6]
            [:a2 :b4 :c7]
            [:a2 :b4 :c8]])
(use 'clojure.contrib.pprint)
(pprint (rows->tree data))
(pprint (tree-map->vec (:children (rows->tree data))))


See http://gist.github.com/448120 for example output.

Hope that helps,

Justin

On Jun 21, 10:55 pm, Base <basselh...@gmail.com> wrote:
> Hi all -
>
> This seems like it should be easy, but for some reason i have thought
> myself into a box on this and now am stuck.
>
> I have a data set of rows/ columns that has some hierarchical data in
> it:
>
> COLUMN  A       B       C
>
>         A1      B1      C1
>         A1      B1      C2
>         A1      B2      C3
>         A1      B2      C4
>         A2      B3      C5
>         A2      B3      C6
>         A2      B4      C7
>         A2      B4      C8
>
> and i want to convert this to a nested map structure:
> [
>         {:data A1
>         :children  [{:data B1 :children [{:data C1} {:data C2}]]}
>                    {:data B2 :children [{:data C3} {:data C4}]]}
>
>         {:data A2
>         :children  [{:data B3 :children [{:data C5} {:data C6}]]}
>                    {:data B4 :children [{:data C7} {:data C8}]]} ]
>
> I have tried various methods and have frustrated myself to no end.
> Any help on this would be most greatly appreciated.
>
> 3 additional notes:
> 1. It would be really awesome if i could somehow specify the
> hierarchical structure so that I can reuse this (as i will have to)
> 2. I will be using this on some fairly large data sets (the largest is
> maybe 50K records).
> 3.  I think that the largest number of nodes in the tree will be 3,
> but this *could* change in the future.
>
> As always, any help is most appreciated.
>
> Thanks
>
> Base

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