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