Here a different version, without the sequence abstraction. I realise its idiomatically obsolete, but thought you guys might enjoy it.
(defn sift "Sift. Old Skool." [key-pred in-s] (reduce (fn [coll elem] (if (key-pred elem) (conj coll [(str elem) []]) (conj (pop coll) [(first (last coll)) (conj (last (last coll)) (str elem))]))) [] in-s)) On Jan 25, 10:21 am, Christophe Grand <christo...@cgrand.net> wrote: > Hi Patrick, > > On Sun, Jan 24, 2010 at 9:58 PM, CuppoJava <patrickli_2...@hotmail.com> wrote: > > It's an elegant puzzle. Thanks Sean! > > > Here's my take: > > (defn sift [pred? s] > > (lazy-seq > > (if (seq s) > > (let [key (first s) > > [vals remaining] (split-with #(not (pred? %)) (rest s))] > > (cons [key vals] (sift pred? remaining)))))) > > > I'm interested in what you came up with. =) > > -Patrick > > Mine looks very much like yours: > (defn sift [pred coll] > (lazy-seq > (when-let [[x & xs] (seq (drop-while (complement pred) coll))] > (cons [x (take-while (complement pred) xs)] (sift pred xs))))) > > except that I discard the first items when they don't match pred, > while you assume that the first item always match pred. > I prefer to use when instead of if when there's no "else" expression. > > I also have a non-lazy solution: > (defn sift [pred coll] > (letfn [(alter-top [v f & args] (conj (pop v) (apply f (peek v) args)))] > (reduce #(if (pred %2) > (conj %1 [%2 []]) > (alter-top %1 alter-top conj %2)) [] coll))) > > Christophe -- 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