Hi Asim,

Thank you for the code and the explanation of the context.

I noticed that partition-after could be implemented by taking my
previous code and incrementing all the 'true' indices by one.  My
first stab:

(defn partition-after [pred coll]
  (if (empty? coll)
    '()
    (let [indices (add-zero (map inc (index-filter pred coll)))
          index-groups (partition-all 2 1 indices)]
      (map #(apply subsequence coll %) index-groups))))

But this returns an extra list at the end if the last element is true,
so I decided to call (remove empty?) on the end result.  This allowed
me to make several other simplifications.  For your consideration, an
index-based implementation of partition-before and partition-after:

(use '[clojure.contrib.seq :only (indexed)])

(defn index-filter [pred coll]
  (when pred
    (for [[idx elt] (indexed coll) :when (pred elt)] idx)))

(defn subsequence
  ([coll start]
     (drop start coll))
  ([coll start end]
     (take (- end start) (drop start coll))))

(defn subsequences [coll indices]
  (let [index-groups (partition-all 2 1 indices)
        subseqs (map #(apply subsequence coll %) index-groups)]
    (remove empty? subseqs)))

(defn partition-before [pred coll]
  (let [indices (cons 0 (index-filter pred coll))]
    (subsequences coll indices)))

(defn partition-after [pred coll]
  (let [indices (cons 0 (map inc (index-filter pred coll)))]
    (subsequences coll indices)))

On Nov 28, 12:17 pm, Asim Jalis <asimja...@gmail.com> wrote:
> Here is partition-before and partition-after -- partition-after is simpler.
>
> (defn partition-before-internal [pred coll]
>   (let [first-item (first coll)]
>    (if (nil? first-item) ()
>      (letfn [(get-partial-partition-with-item []
>                (let [partial-partition (partition-before-internal pred
> (rest coll))]
>                  (cons
>                    (cons
>                      first-item
>                      (first partial-partition))
>                    (rest partial-partition))))]
>        (if (pred first-item)
>          (cons () (lazy-seq (get-partial-partition-with-item)))
>          (get-partial-partition-with-item))))))
>
> (defn partition-before [pred coll]
>   (lazy-seq
>     (let [partition-result (partition-before-internal pred coll)]
>       (if (empty? (first partition-result))
>         (rest partition-result)
>         partition-result))))
>
> (deftest partitioning-before
>   (are [input output] (= ',output (partition-before true? ',input))
>     ()        ()
>     (true)    ((true))
>     (false)   ((false))
>     (false false false true false true true true)
>       ((false false false) (true false) (true) (true) (true))
>     (true false false false true false true true true)
>       ((true false false false) (true false) (true) (true) (true))))
>
> (defn partition-after [pred coll]
>   (lazy-seq
>     (let [first-item (first coll)]
>      (if (nil? first-item) ()
>        (let [partial-partition (lazy-seq (partition-after pred (rest coll)))]
>          (if (pred first-item)
>            (cons (list first-item) partial-partition)
>            (cons
>              (cons
>                first-item
>                (first partial-partition))
>              (rest partial-partition))))))))
>
> (deftest partitioning-after
>   (are [input output] (= ',output (partition-after true? ',input))
>     ()        ()
>     (true)    ((true))
>     (false)   ((false))
>     (false false false true false true true true)
>       ((false false false true) (false true) (true) (true))
>     (true false false false true false true true true)
>       ((true) (false false false true) (false true) (true) (true))))

-- 
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

Reply via email to