私がRacketで作業しているアプリケーションでは、番号のリストを取得し、そのリストを連続する番号のサブリストに分割する必要があります:(実際のアプリケーションでは、実際には、番号といくつかのデータで構成されるペアを分割します、しかし原理は同じです。)
つまり、私のプロシージャが呼び出されchunkify
た場合:
(chunkify '(1 2 3 5 6 7 9 10 11)) -> '((1 2 3) (5 6 7) (9 10 11))
(chunkify '(1 2 3)) -> '((1 2 3))
(chunkify '(1 3 4 5 7 9 10 11 13)) -> '((1) (3 4 5) (7) (9 10 11) (13))
(chunkify '(1)) -> '((1))
(chunkify '()) -> '(())
等
私はRacketで次のことを思いついた:
#lang racket
(define (chunkify lst)
(call-with-values
(lambda ()
(for/fold ([chunk '()] [tail '()]) ([cell (reverse lst)])
(cond
[(empty? chunk) (values (cons cell chunk) tail)]
[(equal? (add1 cell) (first chunk)) (values (cons cell chunk) tail)]
[else (values (list cell) (cons chunk tail))])))
cons))
これは問題なく機能しますが、Racketの表現力を考えると、これを行うためのより簡単で簡単な方法、「値を使用した呼び出し」を取り除く方法、およびリストを逆にする必要があるかどうか疑問に思います。手順などでは、おそらく何らかの形で完全に異なります。
私の最初の試みは、 「The Little Schemer」のコレクターを使用したパターンに非常に大まかに基づいていましたが、それは上記よりもさらに単純ではありませんでした。
(define (chunkify-list lst)
(define (lambda-to-chunkify-list chunk) (list chunk))
(let chunkify1 ([list-of-chunks '()]
[lst lst]
[collector lambda-to-chunkify-list])
(cond
[(empty? (rest lst)) (append list-of-chunks (collector (list (first lst))))]
[(equal? (add1 (first lst)) (second lst))
(chunkify1 list-of-chunks (rest lst)
(lambda (chunk) (collector (cons (first lst) chunk))))]
[else
(chunkify1 (append list-of-chunks
(collector (list (first lst)))) (rest lst) list)])))
私が探しているのは、シンプルで簡潔でわかりやすいものです。