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
-~----------~----~----~----~------~----~------~--~---

Reply via email to