Scheme 对关联列表的键进行分组

;; it requires srfi-1 (lists), for fold-right.
(define (alist-group-keys alist)
  (let ((create-cons-cell-or-append-to-existing 
         (lambda (current acum) 
           (let* ((key (car current))
                  (value (cdr current))
                  (cell (assoc key acum)))
             (if cell ; Key already seen, append current value to the list
                 (begin
                   (set-cdr! cell (cons value (cdr cell)))
                   acum)
                 ;else
                 (cons (list key value) acum))))))
    (fold-right create-cons-cell-or-append-to-existing '() alist)))

;; Example. Given an alist of authors and books:
;
; (alist-group-keys '(("Roth, Henry" . "Call It Sleep")
;                     ("Roth, Henry" . "Mercy of a Rude Stream")
;                     ("Houllebecq, Michel" . "Extension du domaine de la lutte")
;                     ("Houllebecq, Michel" . "Plateforme")))
;
;; It would return the books grouped by author:
;
;(("Roth, Henry" "Call It Sleep" "Mercy of a Rude Stream")
; ("Houllebecq, Michel" "Extension du domaine de la lutte" "Plateforme"))
;