On Sat, Nov 27, 2010 at 5:53 PM, Benny Tsai <benny.t...@gmail.com> wrote: > If you don't mind, I would love to see your version with lazy-seq and > recursion. Seems like that's the idiomatic way of solving problems > like this, judging by the source for the partition functions.
Hi Benny, Certainly. My solution is appended at the bottom. Here is some background on this. I frequently run into this problem where I have lines and I have to group them based on some marker. A simple example is a file containing mail messages in which lines that begin with "^From " mark the start of each new message. To parse this requires a way to start with a sequence of undifferentiated lines and turn that into a sequence of collections of lines each representing a message. And there are really two versions of this partition: partition-before and partition-after: partition-before would put the true with the falses following it, and partition-after will group it with the falses preceding it. Here is the solution I have for partition-before. The function partition-before-internal is almost like partition-before except that it always puts a list of items preceding the first true as its first element. If the first element of coll is true then it sticks an empty list here. (defn partition-before-internal [pred coll] (let [first-item (first coll) second-item (second coll) rest-items (rest coll)] (if (nil? first-item) () (if (nil? second-item) (list () (list first-item)) (letfn [(get-partial-partition-with-item [] (let [partial-partition (partition-before-internal pred rest-items)] (cons (cons first-item (first partial-partition)) (rest partial-partition))))] (if (pred first-item) (cons () (lazy-seq (get-partial-partition-with-item))) (get-partial-partition-with-item))))))) (defn partition-before [pred coll] (lazy-seq (let [partition-result (partition-before-internal pred coll)] (if (empty? (first partition-result)) (rest partition-result) partition-result)))) (deftest partitioning-using-predicate (are [input output] (= ',output (partition-before true? ',input)) () () (true) ((true)) (false) ((false)) (false false false true false true true true) ((false false false) (true false) (true) (true) (true)) (true false false false true false true true true) ((true false false false) (true false) (true) (true) (true)))) -- 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