Path: ...!weretis.net!feeder8.news.weretis.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: "B. Pym" Newsgroups: comp.lang.lisp Subject: Re: How to improve my summarizing code Date: Mon, 24 Jun 2024 15:44:07 -0000 (UTC) Organization: A noiseless patient Spider Lines: 88 Message-ID: References: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Injection-Date: Mon, 24 Jun 2024 17:44:07 +0200 (CEST) Injection-Info: dont-email.me; posting-host="7ceb891a79063de1ea430bfb036aaa7d"; logging-data="1064657"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19kNyABraL/77AOIT2OWg3Y" User-Agent: XanaNews/1.18.1.6 Cancel-Lock: sha1:ihkK6QQe7UCfkuIIARkPBmu9CuU= Bytes: 3251 On 6/23/2024, B. Pym wrote: > Wade Humeniuk wrote: > > > Yeah, but I do not worry about it, much, at the beginning. Here > > is another, it seems easier to think in the morning > > > > (defun summarize (list) > > (let ((summary nil)) > > (map nil (lambda (elt) > > (let ((sum (find (first elt) summary :test #'eql :key #'first))) > > (if sum > > (incf (second sum) (second elt)) > > (push elt summary)))) > > list) > > summary)) > > > > and its loop version > > > > (defun summarize (list) > > (loop with summary = nil > > for elt in list > > for sum = (find (first elt) summary :test #'eql :key #'first) > > if sum do (incf (second sum) (second elt)) > > else do (push elt summary) > > finally (return summary))) > > > > CL-USER 2 > (summarize '((c 7) (a 1) (a 3) (b 1) (b 10) (b 100))) > > ((B 111) (A 4) (C 7)) > > Gauche Scheme > > (use gauche.sequence) ;; group-sequence > > (define (summarize alist) > (map > (lambda(xs) (list (caar xs) (fold + 0 (map cadr xs)))) > (group-sequence alist :key car))) > > (summarize '((c 7) (a 1) (a 3) (b 1) (b 10) (b 100))) > ===> > ((c 7) (a 4) (b 111)) > > > Another way: > > (use srfi-1) ;; list-index > > (define (index x xs) (list-index (cut equal? x <>) xs)) > > (define (summarize alist) > (let1 keys (delete-duplicates (map car alist) ) > (map > cons > keys > (apply map > + > (map > (lambda(kv) > (let1 v (make-vector (length keys) 0) > (vector-set! v (index (car kv) keys) (cadr kv)) > (vector->list v))) > alist))))) > > (summarize '((c 7) (a 1) (a 3) (b 1) (b 10) (b 100))) > ===> > ((c . 7) (a . 4) (b . 111)) Another way: (define (summarize alist) (delete-duplicates (fold (lambda (kv accum) (let* ((k (car kv)) (v (cdr kv)) (n (assoc-ref accum k 0))) (cons (cons k (+ n v)) accum))) '() alist) (lambda(a b)(equal? (car a)(car b))))) (summarize '((c . 7) (a . 1) (a . 3) (b . 1) (b . 10) (b . 100))) ===> ((b . 111) (a . 4) (c . 7))