リストの等分割
リストの中身をn分割したい、というような事があるが、それを実現するような関数は標準では付いてない。(slicesはそれに近いが、割り切れなかったときの挙動が欲しい物と違う。)どういう機能があれば、こういう関数を簡単に書けるのだろう?mapやfoldでは書けない気がする。(foldなら書けるような気はするが、あまり綺麗にはならないと思う。)
結局、再帰を使って書いたのだが、コードにはあまり納得していない。
(use srfi-1) (use util.list) (define (list-divide lst n) (let* ((len (length lst)) (a (truncate (/ len n))) (b (remainder len n))) (let loop ((rest lst) (result '())) (cond ((null? rest) (reverse result)) ((> b 0) (dec! b) (loop (drop rest (+ a 1)) (cons (take rest (+ a 1)) result))) (else (loop (drop* rest a) (cons (take* rest a) result)))))))
- loopに渡す引数に、重複している部分が多すぎるが、まとめようがない。
- 変数名にresultを使うのは良くない。restもいかがなものか。
- (+ a 1)はどこかにまとめるべきか。2箇所なのでどうするべきか非常に迷う。
- aとbには依存関係はないので、letの2段重ねを使えばそれで用は済むのだが、インデントが深くなるし、読みにくくなるように感じたので妥協した。
- 末尾再帰にしてあるところだけは評価する。