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