Sorry, further to that last example, if you actually consume all of
both even and odd sets then the reduce version is more efficient...

(time (let [[a b] (filt-split even? (range 100000))] [(nth a 49999)
(nth b 49999)]))
"Elapsed time: 36.711 msecs"
[99998 99999]

(time (let [[a b] (separate even? (range 100000))] [(nth a 49999) (nth
b 49999)]))
"Elapsed time: 67.004 msecs"
[99998 99999]


On Sun, Mar 8, 2009 at 12:11 PM, Adrian Cuthbertson
<adrian.cuthbert...@gmail.com> wrote:
> You're absolutely right...
>
> user=> (time (let [[a b] (separate even? (range 1000000))] (nth a 3)))
> "Elapsed time: 0.115 msecs"
> 6
> user=> (time (let [[a b] (filt-split even? (range 1000000))] (nth a 3)))
> "Elapsed time: 413.614 msecs"
> 6
>
> and is also more efficient over large sequences...
>
> (time (let [[a b] (filt-split even? (range 100000))] (nth a 49999)))
> "Elapsed time: 44.64 msecs"
> 99998
> user=> (time (let [[a b] (separate even? (range 100000))] (nth a 49999)))
> "Elapsed time: 24.042 msecs"
> 99998
>
> I guess there's only one way to skin this cat :-)
>
>
> On Sun, Mar 8, 2009 at 10:29 AM, Laurent PETIT <laurent.pe...@gmail.com> 
> wrote:
>> It seems to me that neither filt-split nor filter-rem from e are lazy
>> operations (one uses reduce, the other one uses recur).
>> The version in clojurecontrib seems to preserve the original property of
>> filter of returning a lazy sequence.
>>
>> My 0,02€,
>>
>> --
>> Laurent
>>
>> 2009/3/8 Adrian Cuthbertson <adrian.cuthbert...@gmail.com>
>>>
>>> That's the beauty of this language - there are many ways to skin the cat!
>>> Here's a version using reduce...
>>>
>>> (defn filt-split [pred col]
>>>  (reduce (fn [[a b] x] (if (pred x) [(conj a x) b] [a (conj b x)]))
>>> [[] []] col))
>>>
>>> (filt-split even? [1 2 3 4 5 6 7 8])
>>> [[2 4 6 8] [1 3 5 7]]
>>>
>>> But when you look at separate in clojure.contrib.seq-utils its simple
>>> and elegant;
>>> (defn separate [f s]
>>>  [(filter f s) (filter (complement f) s)])
>>> Rgds, Adrian.
>>> - Afficher le texte des messages précédents -
>>> On Sun, Mar 8, 2009 at 6:44 AM, e <evier...@gmail.com> wrote:
>>> > check the discussion with the subject, "time lies, even with doall".  We
>>> > came up with something like the following, but some name change change
>>> > tweaks were suggested.  This thing takes a pred and a collection and
>>> > returns
>>> > a list of two collections -- one that passes the pred, and one that
>>> > fails.
>>> >
>>> > (defn filt-rem [pred coll]
>>> >    (loop [l1 () l2 () [f & r] coll]
>>> >      (if f
>>> >        (if (pred f)
>>> >          (recur (conj l1 f) l2 r)
>>> >          (recur l1 (conj l2 f) r))
>>> >        (list l1 l2))))
>>> >
>>> >
>>> > On Sat, Mar 7, 2009 at 11:37 PM, Jeffrey Straszheim
>>> > <straszheimjeff...@gmail.com> wrote:
>>> >>
>>> >> There is separate in seq_utils in contrib.
>>> >>
>>> >> On Sat, Mar 7, 2009 at 11:29 PM, David Sletten <da...@bosatsu.net>
>>> >> wrote:
>>> >>>
>>> >>> I'm reading the Sequences chapter of Programming Clojure, and Stu
>>> >>> points out that split-with combines the semantics of take-while and
>>> >>> drop-while. But is there a function that does something similar with
>>> >>> "filter"? Namely, rather than simply filtering the elements of a
>>> >>> collection that satisfy a predicate I also want to capture those that
>>> >>> don't. Something like this:
>>> >>> (defn filter-split [pred coll]
>>> >>>   (loop [trues '() falses '() coll coll]
>>> >>>     (cond (empty? coll)
>>> >>>           (vector (reverse trues) (reverse falses))
>>> >>>           (pred (first coll))
>>> >>>           (recur (cons (first coll) trues) falses (rest coll))
>>> >>>           :else
>>> >>>           (recur trues (cons (first coll) falses) (rest coll)))))
>>> >>>
>>> >>> (filter-split #{\a\e\i\o\u} "is this not pung?") => [(\i \i \o \u)
>>> >>> (\s \space \t \h \s \space \n \t \space \p \n \g \?)]
>>> >>> (filter-split even? (range 10)) => [(0 2 4 6 8) (1 3 5 7 9)]
>>> >>>
>>> >>> Aloha,
>>> >>> David Sletten
>>> >>>
>>> >>>
>>> >>
>>> >>
>>> >>
>>> >
>>> >
>>> > >
>>> >
>>>
>>>
>>
>>
>> >>
>>
>

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