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

Reply via email to