I have used the following in the past in some utils I have for seqs:
(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 value increment
(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/partition is the old clojure contrib str-utils2 - it's a while since
I did this
Dave
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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en