For the transducer version, I don’t think you need to keep track of the
previous value (fval). The decision to start a new partition group depends only
on the current item. Here’s my version. (Warning: virtually untested.) I
assume that the first item goes into the first partition no matter what so you
don’t even need to call f. Maybe you should for side-effects?
(defn partition-when
"Applies f to each value in coll, starting a new partition each time f
returns a
true value. Returns a lazy seq of partitions. Returns a stateful
transducer when no collection is provided."
{:added "1.X"
:static true}
([f]
(fn [rf]
(let [a (java.util.ArrayList.)]
(fn
([] (rf))
([result]
(let [result (if (.isEmpty a)
result
(let [v (vec (.toArray a))]
;;clear first!
(.clear a)
(unreduced (rf result v))))]
(rf result)))
([result input]
(if (.isEmpty a)
(do (.add a input)
result)
(if (f input)
(let [v (vec (.toArray a))]
(.clear a)
(let [ret (rf result v)]
(when-not (reduced? ret)
(.add a input))
ret))
(do
(.add a input)
result))))))))
([f coll]
(lazy-seq
(when-let [s (seq coll)]
(let [fst (first s)
run (cons fst (take-while #(not (f %)) (next s)))]
(cons run (partition-when f (seq (drop (count run) s)))))))))
— Steve
> On Mar 5, 2015, at 12:11 PM, Andy- <[email protected]> wrote:
>
> Tried myself and my first transducer for fun:
>
> (defn partition-when
> [f]
> (fn [rf]
> (let [a (java.util.ArrayList.)
> fval (volatile! false)]
> (fn
> ([] (rf))
> ([result]
> (let [result (if (.isEmpty a)
> result
> (let [v (vec (.toArray a))]
> ;;clear first!
> (.clear a)
> (unreduced (rf result v))))]
> (rf result)))
> ([result input]
> (if-not (and (f input) @fval)
> (do
> (vreset! fval true)
> (.add a input)
> result)
> (let [v (vec (.toArray a))]
> (.clear a)
> (let [ret (rf result v)]
> (when-not (reduced? ret)
> (.add a input))
> ret))))))))
>
>
> (into [] (partition-when
> #(.startsWith % ">>"))
> [">> 1" ">> 2" "22" ">> 3"])
>
> Based on partition-by (on master branch). Would be interesting how fast it is
> compared to the other implementations.
>
> Any comments appreciated.
>
> Cheers
--
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
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.