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 <[email protected]> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en