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- <andre.r...@gmail.com> 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 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
--- 
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 clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to