Hi John,

As miner mentioned, peek is preferable to last for vectors. Here is an 
implementation based on the observation that consecutive increasing numbers 
are equivalent when you subtract their indices. Maybe it is more clever 
than simple.

(ns experimental-clojure.congeal-consecutives)

(def v [1 3 4 5 7 9 10 11 12])
 (defn congeal-consecutives [coll]
  (->> coll
       (map-indexed (fn [i x] [(- x i) x]))
       (partition-by first)
       (mapv (fn [pairs]
               (mapv second pairs)))))
 (defn rangify [coll]
  (mapv (fn [r]
          (assert (vector? coll))
          (let [f    (first r)
                top  (peek  r)]
            (if (= f top)
              (str f)
              (str f "-" top)))) coll))
 (-> v
    congeal-consecutives
    rangify)


https://gist.github.com/johnwalker/8e7e6a8bcbeff03d4e80


On Thursday, November 6, 2014 2:22:14 PM UTC-8, John Gabriele wrote:
>
> Hi all,
>
> I've got this: `[1 3 4 5 7 9 10 11 12]`
> and I'd like to turn it into this: `[[1] [3 4 5] [7] [9 10 11 12]]`.
>
> That is, I'd like to group consecutive numbers together (the final goal 
> being to produce something like `["1" "3-5" "7" "9-12"]`, but that's the 
> easy part).
>
> I haven't found an easy way to do this. Here's what I've come up with in 
> Clojure:
>
> ~~~clojure
> #!/usr/bin/env lein-exec
>
> (def v [1 3 4 5 7 9 10 11 12])
>
> (defn congeal-consecutives
>   [coll]
>   (reduce (fn [accum x]
>             (if (= x (inc (last (last accum))))
>               (concat (butlast accum)
>                       [(conj (last accum) x)])
>               (concat accum
>                       [[x]])))
>           [[(first coll)]]
>           (rest coll)))
>
> (prn (congeal-consecutives v))
> ~~~
>
> and here's it done in Python:
>
> ~~~python
> #!/usr/bin/python3
>
> v = [1, 3, 4, 5, 7, 9, 10, 11, 12]
>
> def congeal_consecutives(coll):
>     accum = [[ coll[0] ]]
>     more  = coll[1:]
>     for x in more:
>         if x == accum[-1][-1] + 1:
>             accum[-1].append(x)
>         else:
>             accum.append([x])
>     return accum
>
> print(congeal_consecutives(v))
> ~~~
>
> Can anyone suggest a better / simpler / more easily-understandable way to 
> do this in Clojure?
>
> Thanks,
> -- John
>
>

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