Search code examples
clojureiterationtake

clojure split collection in chunks of increasing size


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)

Solution

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