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