2

Hi I am a clojure newbie,

I am trying to create a function that splits a collection into chunks of increasing size something along the lines of

(apply #(#(take %) (range 1 n)) col)

where n is the number of chunks

example of expected output: with n = 4 and col = (range 1 4)

(1) (2 3) (4)

with n = 7 and col = (range 1 7)

(1) (2 3) (4 5 6) (7)
maazza
  • 7,016
  • 15
  • 63
  • 96

4 Answers4

5

You can use something like this:

(defn partition-inc
  "Partition xs at increasing steps of n" 
  [n xs] 
  (lazy-seq 
    (when (seq xs) 
      (cons (take n xs) 
            (partition-inc (inc n) (drop n xs))))))

; (println (take 5 (partition-inc 1 (range))))
; → ((0) (1 2) (3 4 5) (6 7 8 9) (10 11 12 13 14))

Or if you want to have more influence, you could alternatively provide a sequence for the sizes (behaves the same as above, if passed (iterate inc 1) for sizes:

(defn partition-sizes
  "Partition xs into chunks given by sizes"
  [sizes xs]
  (lazy-seq
    (when (and (seq sizes) (seq xs))
      (let [n (first sizes)]
        (cons (take n xs) (partition-sizes (rest sizes) (drop n xs)))))))

; (println (take 5 (partition-sizes (range 1 10 2) (range))))
; → ((0) (1 2 3) (4 5 6 7 8) (9 10 11 12 13 14 15) (16 17 18 19 20 21 22 23 24))
cfrick
  • 35,203
  • 6
  • 56
  • 68
2

An eager solution would look like

(defn partition-inc [coll]
  (loop [rt [], c (seq coll), n 1]
    (if (seq c)
      (recur (conj rt (take n c)) (drop n c) (inc n))
      rt)))
xificurC
  • 1,168
  • 1
  • 9
  • 17
2

another way would be to employ some clojure sequences functions:

(->> (reductions (fn [[_ x] n] (split-at n x))
                 [[] (range 1 8)]
                 (iterate inc 1))
     (map first)
     rest
     (take-while seq))

;;=> ((1) (2 3) (4 5 6) (7))
leetwinski
  • 17,408
  • 2
  • 18
  • 42
2

Yet another approach...

(defn growing-chunks [src]
  (->> (range)
       (reductions #(drop %2 %1) src)
       (take-while seq)
       (map-indexed take)
       rest))

(growing-chunks [:a :b :c :d :e :f :g :h :i])
;; => ((:a) (:b :c) (:d :e :f) (:g :h :i))
Rulle
  • 4,496
  • 1
  • 15
  • 21