On Fri, Sep 10, 2010 at 4:26 PM, Matt Smith <m0sm...@gmail.com> wrote: > problem: convert a collection [1 2 0 1 2 3 0 1 2 3 0 0 1 2] into > partitions like: > ((1 2) (0 1 2 3) (0 1 2 3) (0) (0 1 2)) > In this case, start each partition on a 0. > > > I looked at the various partition functions but none of them would do > the trick without adding unnecessary complexity. Instead I wrote a > new function based on partition-by: > > Solution: > (defn partition-starting-every > "Partition the sequence starting each partition when the f is true." > [f coll] > (if-let [coll (seq coll)] > (let [p (cons (first coll) (take-while (complement f) (rest > coll)))] > (lazy-seq (cons p (partition-starting-every f (drop (count p) > coll))))))) > > user=>(partition-starting-every zero? [1 2 0 1 2 3 0 1 2 3 0 0 1 2]) > ((1 2) (0 1 2 3) (0 1 2 3) (0) (0 1 2))
Iteration at a rate other than once per input seq item suggests iterate: (defn partition-starting-every [f coll] (->> [nil coll] (iterate (fn [[p [x :as s1]]] (let [[n s2] (split-with (complement f) (next s1))] (when (seq s1) [(cons x n) s2])))) (map first) next (take-while identity))) Ugh. Well, maybe partition-by can be used after all: (defn partition-starting-every [f coll] (let [pb (partition-by #(and (f %) (Object.)) coll)] (->> (map (fn [[a :as as] [b :as bs]] (cond (nil? as) (when-not (f b) bs) (and (f a) (f b)) as (f a) (concat as bs))) (cons nil pb) pb) (remove nil?)))) Bleh. Looks lazy-seq is the way to go. :-) BTW, it's generally best to have the lazy-seq outside the empty test to make your fn as lazy as possible. And I'd use split-with: (defn partition-starting-every "Partition the sequence starting each partition when the f is true." [f coll] (lazy-seq (when-let [[x & xs] (seq coll)] (let [[a b] (split-with (complement f) xs)] (cons (cons x a) (partition-starting-every f b)))))) --Chouser http://joyofclojure.com/ -- 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