Here's a fixed version that...
1. Is lazy everywhere.
2. No longer loses elements :)
(use '[clojure.contrib.seq :only (indexed)])
(defn index-filter [pred coll]
(when pred
(for [[idx elt] (indexed coll) :when (pred elt)] idx)))
(defn subsequence [coll start end]
(take (- end start) (drop start coll)))
(defn split-when [pred coll]
(let [coll-end (count coll)
indices (distinct (concat [0] (index-filter pred coll) [coll-end]))
index-pairs (partition 2 1 indices)]
(for [[start end] index-pairs] (subsequence coll start end))))
On Nov 27, 5:07 pm, Benny Tsai <[email protected]> wrote:
> > Subvec, however, isn't lazy.
>
> That's true. I just realized there's another problem with my approach
> as well: it does not preserve elements before the first true index.
>
> user=> (partition-when true? [false true])
> ([true])
>
> When the result should probably be:
>
> user=> (partition-when true? [false true])
> ((false) (true))
>
> On Nov 27, 2:05 pm, Ken Wesson <[email protected]> wrote:
>
>
>
>
>
>
>
> > Subvec, however, isn't lazy. This is:
>
> > (defn split-when [pred coll]
> > (let [ipred (complement pred)
> > bits (iterate
> > (fn [[out coll]]
> > (let [[a b] (split-with ipred (rest coll))]
> > [(cons (first coll) a) b]))
> > [nil coll])]
> > (map #(first (first %))
> > (take-while #(seq (second (second %))) (map vector (rest bits)
> > bits)))))
>
> > user=> (take 10 (split-when #(= 0 (rem % 3)) (iterate inc 1)))
> > ((1 2)
> > (3 4 5)
> > (6 7 8)
> > (9 10 11)
> > (12 13 14)
> > (15 16 17)
> > (18 19 20)
> > (21 22 23)
> > (24 25 26)
> > (27 28 29))
--
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