Hi Greg, Welcome to Clojure!
I haven't scrutinized your code, but at a glance it looks like your implementations are very idiomatic. It also seems right to me that these functions can't be implemented directly in terms of take-while and partition-by. Without more thought I can't say if there are more direct implementations than yours, but I wanted to compliment you anyway on getting your hands dirty. These look like useful functions. Perhaps someone who knows c.c.seq well can say more. Here's another implementation of take-to-first, just for comparison's sake. I tried to use the standard sequence functions. Yours is twice as fast and more readable. (defn take-to-first [pred coll] (if (seq coll) (map last (take-while (comp (complement pred) first) (cons (list (first coll)) (partition 2 1 coll)))) (lazy-seq))) Garth On Mon, Mar 15, 2010 at 1:24 PM, Greg Fodor <gfo...@gmail.com> wrote: > 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<clojure%2bunsubscr...@googlegroups.com> > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > -- 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