Beispiel:
Wie man die Liste umwandelt:
'(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
In die Liste der Listen:
'((0 1 2 3) (4 5 6 7) (8 9 10 11) (12 13 14 15))
Auf der Grundlage der bisherigen Antworten habe ich mir Folgendes überlegt:
Definieren Sie zunächst eine Funktion, die bis zu 'n' Elemente vom Anfang der Liste aufnimmt:
(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 '()))
Die zweite ist eine ähnliche Funktion für den Rest der Liste:
(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 '()))
Das hätte man auch als eine Funktion machen können, die zwei Werte zurückgibt, und Racket hat eine Funktion 'split-at', die das gleiche Ergebnis liefert, aber ich habe das als Übung gemacht.
ps. Ist dies die korrekte Anwendung der Schwanzrekursion?
Dann kann Split-in-Chunks wie folgt geschrieben werden:
(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. Kann diese noch weiter verbessert werden oder ist sie "gut genug"?