Can I play too? Non-lazy version (basically the same as Chouser's with reduce instead of loop): (defn partition-when [pred coll] (reduce #(if (pred %2) (conj %1 [%2]) (conj (pop %1) (conj (peek %1) %2))) [[]] coll))
user=> (partition-when odd? (range 1 15)) [[] [1 2] [3 4] [5 6] [7 8] [9 10] [11 12] [13 14]] user=> (partition-when even? (range 1 15)) [[1] [2 3] [4 5] [6 7] [8 9] [10 11] [12 13] [14]] And lazy version: (defn partition-when [pred coll] (let [heads (partial take-while (complement pred))] (cons (heads coll) (mapcat #(when (pred %1) [(cons %1 (heads %2))]) coll (iterate rest (rest coll)))))) user=> (partition-when odd? (range 1 15)) (() (1 2) (3 4) (5 6) (7 8) (9 10) (11 12) (13 14)) user=> (partition-when even? (range 1 15)) ((1) (2 3) (4 5) (6 7) (8 9) (10 11) (12 13) (14)) Christophe On Sat, Nov 7, 2009 at 1:47 AM, Alex Osborne <a...@meshy.org> wrote: > > Alex Osborne wrote: >> Like Mark's but using split-with instead of split-at: >> >> (defn partition-when [pred coll] >> (lazy-seq >> (when-let [[x & xs] (seq coll)] >> (let [[xs ys] (split-with (complement pred) xs)] >> (cons (cons x xs) (partition-when pred ys)))))) > > Just realised this is almost the same as Warren's -- I had missed > reading Warren's before posting. Thought it might be helpful if I > explain the differences: > > * lazy-seq on the outside of the conditional. This means the seq is > fully lazy, so if you never call first/next on it, nothing is ever run. > > * As suggested by others complement instead of NOT. > > * (when (seq coll) ...) instead of (if (empty? coll) () ...). We can > simplify things like this as (lazy-seq nil) => () and (seq ()) => nil. > > * Using destructuring instead of (first coll) (next coll). Makes it a > bit shorter and is quite useful if you're going to use the result of > (first coll) or (next coll) multiple times, but in this case it doesn't > really matter. > > > > -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.cgrand.net/ (en) --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---