I have used the following (from a bunch of utils I have for seqs) in the past to do this kind of thing.
You will need to define the reduce-fn and the predicate you need. examples below in the comment. (defn take-while-reduce "fancy take accumulating a reduced value on taken items this value can then be tested in the take fn e.g (take-while-reduce 0 (fn [v i] (inc v)) (fn [v i] (= v i)) [1 2 3 5 6 7]) => (1 2 3)" [initial reduce-fn pred coll] (when-let [s (seq coll)] (let [[f & r] coll reduce-value (reduce-fn initial f)] (if (pred reduce-value f) (cons f (take-while-reduce reduce-value reduce-fn pred r)))))) (comment ;; examples (take-while-reduce 0 (fn [v i] (inc v)) (fn [v i] (= v i)) [1 2 3 5 6 7]) ;; acts like a line break (take-while-reduce 0 (fn [v i] (+ v (count i))) (fn [v i] (< v 20)) (ccsu/partition "the quick brown fox jumps" #"\s+")) ) ; ccsu is the old clojure contrin str-utils2 On Friday, 31 August 2012 22:08:03 UTC+10, shaobohou wrote: > > Hi, > > I am trying to write a function which takes a list of strings, tokenize > each one, and maximise N such that the number of unique tokens in the first > N strings is less than > some number M. > > I have written the following function using take-while and a pred function > with an atom to store the set of unique tokens. It works and is just as > fast as a messier loop/recur version. > > (defn take-as-many-as-possible-until > [ss tok-fn m] > (let [items (atom #{})] > (-> (fn [v] > (swap! items (partial apply merge) (tok-fn v)) > (< (count @items) m)) > (take-while ss)))) > > However, I have noticed that the take-while documentation says that the > pred function should be side-effect free. Will this be problem in my > implementation if I am calling it from multiple threads? And what would be > the more idiomatic way of implementing this kind of behaviour? > > Thanks, > Shaobo > > > > -- 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