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.

Reply via email to