Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: "B. Pym" Newsgroups: comp.lang.lisp Subject: Re: Any way to collect all the values of a hash table more concisely ? Date: Fri, 5 Jul 2024 22:09:09 -0000 (UTC) Organization: A noiseless patient Spider Lines: 37 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Injection-Date: Sat, 06 Jul 2024 00:09:10 +0200 (CEST) Injection-Info: dont-email.me; posting-host="36dabbcb546c8dd3a3c5c81a41ee2e18"; logging-data="3644220"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18bh6ihYUj9ioTmmqOSDDoJ" User-Agent: XanaNews/1.18.1.6 Cancel-Lock: sha1:SPNv4WU90oR3OBkZWGGfn1EwL8s= Bytes: 2176 > > So this new version works as intended: > > > (defun cluster-by (fn list &aux (clusters (make-hash-table)) (result nil)) > > (mapcar #'(lambda (x) (push x (gethash (funcall fn x) clusters))) list) > > (maphash #'(lambda (key value) (push value result)) clusters) > > (sort result #'< :key #'(lambda (x) (length (car x))))) > > Um, sorry: > > (defun cluster-by (fn list &aux (clusters (make-hash-table)) (result nil)) > (mapcar #'(lambda (x) (push x (gethash (funcall fn x) clusters))) list) > (maphash #'(lambda (key value) (push value result)) clusters) > (sort result #'< :key #'(lambda (x) (funcall fn (car x))))) > ^^^^^^^^^^ "lambda" is a macro that expands to (function (lambda ...)). So instead of #'(lambda he ought to use (lambda The poster prefers #'lambda because he prefers ugliness. Common Lisp is used by those who want code to be as hideous as possible. Gauche Scheme (define (cluster-by fn lst) (let ((clusters (make-hash-table 'equal?))) (dolist (k lst) (hash-table-push! clusters (fn k) k)) (hash-table-values clusters))) (cluster-by string-length '("a" "b" "abc" "bc" "a" "abcd" "e" "fg")) ===> (("abcd") ("e" "a" "b" "a") ("fg" "bc") ("abc"))