Re: partition-when?
If you’re interested in a transducer version of partition-when, here’s my code from https://github.com/miner/transmuters ;; collection version by Frank on mailing list ;; SEM added transducer version, adapted from partition-by (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. {: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) -- 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.
Re: partition-when?
Gorgeous! Thanks, Moe! (Chris says hi back :)) On Aug 19, 2015, at 7:51 PM, Moe Aboulkheir m...@nervous.io wrote: Laurens, I don't think I've encountered an identical function I can point you to, but here's an alternative implementation: (defn partition-when [pred coll] (lazy-seq (when-let [[h t] (seq coll)] (let [[run remains] (split-with (complement pred) t)] (cons (cons h run) (partition-when pred remains)) Do you like that any better? P.S: Say Hi to Chris for me! Take care, Moe On Thu, Aug 20, 2015 at 1:34 AM, Laurens Van Houtven _...@lvh.io mailto:_...@lvh.io wrote: Hi, I needed a function that partitions (coll a) = (coll (coll a)), starting a new subcoll whenever a given pred is true. Use case: I have a sequence of rows; these rows form groups; I want to group them. A group is started by a header; so I want a new coll whenever my is-header? pred returns true. I found an implementation that used partition-by on the mailing list, but this had some issues: if multiple elems next to each other were true under the pred, it wouldn’t create a new pred for each one. I came up with the following implementation. (defn ^:private partition-when Partitions the coll whenever (f elem) is true. [pred coll] (- (reduce (fn [[first rest :as groups] elem] (if (pred elem) (conj groups [elem]) (conj rest (conj first elem '() coll) reverse)) It feels like this could be written a *lot* better. With Haskell’s Data.List.Split, this becomes: partitionWith p xs = filter (/= []) (split (whenElt p) xs) (thanks to my colleague Christopher Armstrong for the help with the Haskell version) It would *almost* be partitionWith p = split (whenElt p), but for some reason split sometimes returns empty lists. Granted, this is a specialized library; I’d be more than happy to get partition-when from a 3rd party. It’d be even nicer if it was in Clojure though :) thanks lvh -- 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 mailto: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 mailto:clojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en 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 mailto:clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout https://groups.google.com/d/optout. -- 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 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 mailto:clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout https://groups.google.com/d/optout. -- 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.
Re: partition-when?
Laurens, I don't think I've encountered an identical function I can point you to, but here's an alternative implementation: (defn partition-when [pred coll] (lazy-seq (when-let [[h t] (seq coll)] (let [[run remains] (split-with (complement pred) t)] (cons (cons h run) (partition-when pred remains)) Do you like that any better? P.S: Say Hi to Chris for me! Take care, Moe On Thu, Aug 20, 2015 at 1:34 AM, Laurens Van Houtven _...@lvh.io wrote: Hi, I needed a function that partitions (coll a) = (coll (coll a)), starting a new subcoll whenever a given pred is true. Use case: I have a sequence of rows; these rows form groups; I want to group them. A group is started by a header; so I want a new coll whenever my is-header? pred returns true. I found an implementation that used partition-by on the mailing list, but this had some issues: if multiple elems next to each other were true under the pred, it wouldn’t create a new pred for each one. I came up with the following implementation. (defn ^:private partition-when Partitions the coll whenever (f elem) is true. [pred coll] (- (reduce (fn [[first rest :as groups] elem] (if (pred elem) (conj groups [elem]) (conj rest (conj first elem '() coll) reverse)) It feels like this could be written a *lot* better. With Haskell’s Data.List.Split, this becomes: partitionWith p xs = filter (/= []) (split (whenElt p) xs) (thanks to my colleague Christopher Armstrong for the help with the Haskell version) It would *almost* be partitionWith p = split (whenElt p), but for some reason split sometimes returns empty lists. Granted, this is a specialized library; I’d be more than happy to get partition-when from a 3rd party. It’d be even nicer if it was in Clojure though :) thanks lvh -- 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. -- 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.
Re: partition-when
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.
Re: partition-when
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 On Tuesday, March 3, 2015 at 2:46:29 PM UTC-5, Frank wrote: Hi all, for some tests I need a function which starts a new partition each time a predicate returns true, for instance: (partition-when (fn [s] (.startsWith s )) [ 1 2 3 4 5 6]) := [[ 1 2 3] [ 4 5 6]] Since I haven't found a built-in function, I copied, pasted, and modified the core function partition-by: (defn partition-when [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 Is there a better (more idiomatic) way to achieve the same result? Thank you in advance. Frank -- 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.
Re: partition-when
Hi Frank, I use a similar function that combines partition-by and partition-all: (defn partition-when [f coll] (map (partial apply concat) (partition-all 2 (partition-by f coll Martin. On Wed, Mar 4, 2015 at 10:19 PM, Ivan L ivan.laza...@gmail.com wrote: I went though almost the exact same exercise and my code is almost identical to yours. I called it partition-every and I use it a lot. A more determined individual might submit this for inclusion into core! On Tuesday, March 3, 2015 at 2:46:29 PM UTC-5, Frank wrote: Hi all, for some tests I need a function which starts a new partition each time a predicate returns true, for instance: (partition-when (fn [s] (.startsWith s )) [ 1 2 3 4 5 6]) := [[ 1 2 3] [ 4 5 6]] Since I haven't found a built-in function, I copied, pasted, and modified the core function partition-by: (defn partition-when [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 Is there a better (more idiomatic) way to achieve the same result? Thank you in advance. Frank -- 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. -- 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.
Re: partition-when
I went though almost the exact same exercise and my code is almost identical to yours. I called it partition-every and I use it a lot. A more determined individual might submit this for inclusion into core! On Tuesday, March 3, 2015 at 2:46:29 PM UTC-5, Frank wrote: Hi all, for some tests I need a function which starts a new partition each time a predicate returns true, for instance: (partition-when (fn [s] (.startsWith s )) [ 1 2 3 4 5 6]) := [[ 1 2 3] [ 4 5 6]] Since I haven't found a built-in function, I copied, pasted, and modified the core function partition-by: (defn partition-when [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 Is there a better (more idiomatic) way to achieve the same result? Thank you in advance. Frank -- 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.