Created
February 12, 2011 18:23
-
-
Save Chouser/823958 to your computer and use it in GitHub Desktop.
Very raw version of a function to turn a seq into a lazy tree
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn seq-tree | |
"Takes a sequential collection of events that logically represents | |
a tree by each event being one of: enter-sub-tree event, | |
exit-sub-tree event, or node event. Returns a lazy sequence whose | |
first element is a sequence of sub-trees and whose remaining | |
elements are events that are not siblings or descendants of the | |
initial event. The given exit? function must return true for any | |
exit-sub-tree event. parent must be a function of two arguments: | |
the first is an event, the second a sequence of nodes or subtrees | |
that are children of the event. parent must return nil or false if | |
the event is not an enter-sub-tree event. Any other return value | |
will become a sub-tree of the output tree and should normally | |
contain in some way the children passed as the second arg. The node | |
function is called with a single event arg on every node event and | |
its return value will become a node of the output tree. | |
(seq-tree #(when (= %1 :<) {:content %2}) #{:>} vector | |
[1 2 :< 3 :< 4 :> :> 5 :> 6]) | |
;=> (([1] [2] {:content ([3] {:content ([4])})} [5]) 6)" | |
[parent exit? node coll] | |
(lazy-seq | |
(when-let [[event] (seq coll)] | |
(let [more (rest coll)] | |
(if (exit? event) | |
(cons nil more) | |
(let [tree (seq-tree parent exit? node more)] | |
(if-let [p (parent event (lazy-seq (first tree)))] | |
(let [subtree (seq-tree parent exit? node (lazy-seq (rest tree)))] | |
(cons (cons p (lazy-seq (first subtree))) | |
(lazy-seq (rest subtree)))) | |
(cons (cons (node event) (lazy-seq (first tree))) | |
(lazy-seq (rest tree)))))))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment