I think the following function does what you want (I've also published
it @ http://gist.github.com/449266 if you find Gists prettier):
(defn munge [vs]
(if (== 1 (count (first vs)))
(reduce into vs)
(let [gs (group-by #(% 0) vs)]
(map (fn [k v]
{:data k :children v})
(keys gs)
(->> (vals gs)
(map (partial map #(subvec % 1)))
(map munge))))))
A sample interaction at the REPL:
user> (def test-data
[[:a1 :b1 :c1]
[:a1 :b1 :c2]
[:a1 :b2 :c3]
[:a1 :b2 :c4]
[:a2 :b3 :c5]
[:a2 :b3 :c6]
[:a2 :b4 :c7]
[:a2 :b4 :c8]])
#'user/test-data
user> (pprint (munge test-data))
({:data :a1,
:children
({:data :b1, :children [:c1 :c2]} {:data :b2, :children [:c3 :c4]})}
{:data :a2,
:children
({:data :b3, :children [:c5 :c6]} {:data :b4, :children [:c7 :c8]})})
If you decide to go the "keyd by field value" route (no :data /
:children), here's a simplified version to do it:
(defn munge [vs]
(if (== 1 (count (first vs)))
(reduce into vs)
(let [gs (group-by #(% 0) vs)]
(zipmap (keys gs)
(->> (vals gs)
(map (partial map #(subvec % 1)))
(map munge))))))
user> (pprint (munge test-data))
{:a2 {:b4 [:c7 :c8], :b3 [:c5 :c6]},
:a1 {:b2 [:c3 :c4], :b1 [:c1 :c2]}}
Of course you cannot beat David's version for simple elegance if the
format it produces is acceptable...
Sincerely,
Michał
--
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