Here's something based on a similar question I asked in #clojure the other day, based on the code Chousuke answered with (all ugliness is my fault).
(defn cond [f pred] (fn [coll acc outp] (if (empty? coll) (conj outp acc) (if (pred (first coll)) (recur (rest coll) (vector (first coll)) (conj outp acc)) (recur (rest coll) (f acc (first coll)) outp))))) ((cond conj (partial < 5)) [1 2 3 4 5 6 7 9 2 1 2 3] '[] '[]) user=> [[1 2 3 4 5] [6] [7] [9 2 1 2 3]] Edmund On 7 Nov 2009, at 14:17, Christophe Grand wrote: > > 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) > > > Edmund "The future is here. It's just not widely distributed yet" -- Gibson --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---