8
Example:
How to convert list:
'(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
Into list of lists:
'((0 1 2 3) (4 5 6 7) (8 9 10 11) (12 13 14 15))
Based on answers provided here so far, this is what I've come up with:
First define function to take up to 'n' elements from beginning of the list:
(define (take-up-to n xs)
(define (iter xs n taken)
(cond
[(or (zero? n) (empty? xs)) (reverse taken)]
[else (iter (cdr xs) (- n 1) (cons (car xs) taken))]))
(iter xs n '()))
Second is similar function for the rest of list:
(define (drop-up-to n xs)
(define (iter xs n taken)
(cond
[(or (zero? n) (empty? xs)) xs]
[else (iter (cdr xs) (- n 1) (cons (car xs) taken))]))
(iter xs n '()))
This could have been done as one function that returns two values and Racket has a function 'split-at' that produces same result, but I did this as an exercise.
ps. Is this correct use of tail recursion ?
Than split-into-chunks can be written like this:
(define (split-into-chunks n xs)
(if (null? xs)
'()
(let ((first-chunk (take-up-to n xs))
(rest-of-list (drop-up-to n xs)))
(cons first-chunk (split-into-chunks n rest-of-list)))))
pps. Can this one be improved even more or is it 'good enough' ?