Re: partition-when?

2015-08-20 Thread Steve Miner
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?

2015-08-20 Thread Laurens Van Houtven
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?

2015-08-19 Thread Moe Aboulkheir
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

2015-03-05 Thread Steve Miner
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

2015-03-05 Thread Andy-
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

2015-03-05 Thread Martin Harrigan
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

2015-03-04 Thread Ivan L
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.