Hi there, I am just learning Clojure and am processing some BER
encoded integer values. Basically, the most significant bit of the
integer in the stream indicates the split point between integers, and
so I was looking into partition-by to see if that would help. Turns
out, what I really need are two complementary functions: take-to-first
and partition-when. Take-to-first is similar to take-while, but is
*inclusive* and also inverts the boolean. For example:

Clojure=> (take-to-first even? [1 1 1 1])
(1 1 1 1)
Clojure=> (take-to-first even? [1 1 1 1 2 3 3 3])
(1 1 1 1 2)
Clojure=> (take-to-first even? [2 2 2 ])
(2)

Additionally, partition-when runs through the seq and partitions it on
demand when a predicate is true. (Leaving the entry where it is seen
to be true in the current partition:

Clojure=> (partition-when even? [1 1 1 2 3 3 3 4 3 3 3 4 3 3 3])
((1 1 1 2) (3 3 3 4) (3 3 3 4) (3 3 3))
Clojure=> (partition-when even? [1 1 1])
((1 1 1))
Clojure=> (partition-when even? [1 1 1 2 3 3 3])
((1 1 1 2) (3 3 3))
Clojure=> (partition-when even? [2 2 2 2])
((2) (2) (2) (2))

These seem to sit aside the current take and partitioning functions
since they are basically looking at an truth value that indicates a
partition or stopping event that we want to capture and cease moving
forward. Here is the source:

(defn take-to-first
  "Returns a lazy sequence of successive items from coll up to
  and including the point at which it (pred item) returns true.
  pred must be free of side-effects."
  [pred coll]
  (lazy-seq
   (when-let [s (seq coll)]
       (if-not (pred (first s))
         (cons (first s) (take-to pred (rest s)))
         (list (first s))))))

(defn partition-when
  "Applies f to each value in coll, splitting it each time f returns
   true. Returns a lazy seq of lazy seqs."
  [f coll]
  (when-let [s (seq coll)]
    (let [run (take-to-first #(f %) s)
          res (drop (count run) s)]
      (lazy-seq
        (cons run (partition-when f res))))))

I think these could make a good addition to clojure.contrib.seq.
Please let me know if there is an easier way to get this in if you
agree. Also, please let me know if these are the best ways to write
these functions, since I am still a newbie!

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