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

Reply via email to