Warning: mysqli::__construct(): (HY000/1203): User howardkn already has more than 'max_user_connections' active connections in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\includes\artfuncs.php on line 21
Failed to connect to MySQL: (1203) User howardkn already has more than 'max_user_connections' active connectionsPath: ...!2.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: "B. Pym" Newsgroups: comp.lang.lisp,comp.lang.scheme Subject: Re: Basic List processing Date: Fri, 30 Aug 2024 21:51:54 -0000 (UTC) Organization: A noiseless patient Spider Lines: 99 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Injection-Date: Fri, 30 Aug 2024 23:51:54 +0200 (CEST) Injection-Info: dont-email.me; posting-host="5f0439c3c250d854a4c9ef1a4e01f9df"; logging-data="706465"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+yLR9zh+Efv2ULNp81JR41" User-Agent: XanaNews/1.18.1.6 Cancel-Lock: sha1:38RtFLLtQIAef5z208HNC7Csdb8= Bytes: 3590 > > Suppose I have: > > > > (defvar *list* > > '((1 2) > > (3 4) > > (5 6) > > (1 7))) > > > > > > Now, suppose I want the "keys" of the list, defined by the first element > > of the list. Is there a Lisp function which is callable something like: > > (keys *list* :key #'first) ; => '(1 3 5) > > > > Suppose further that I want to accumulate totals based on keys. The > > first element in the list is the key, and the second element in the list > > is the value. Is there a Lisp function which is callable something like: > > (accum *list*) ; => '( (1 9) (3 4) (5 6) ) > > What we can do is define a somewhat general function for processing this type > of associative list. > > (defun histogram (assoc-list reduce-func &rest reduce-args) > (let ((hash (make-hash-table :test #'eql))) > (loop for (key value) in assoc-list > do (push value (gethash key hash))) > (loop for key being the hash-keys of hash > using (hash-value value-list) > collect `(,key > ,(apply #'reduce reduce-func value-list reduce-args))))) > > What HISTOGRAM does is collates the values that share the same key into > lists, and then it processes each list through REDUCE, so that you can > summarize the values using arbitrary arithmetic, not only addition. > > Some tests: > > Add: > > (histogram '((1 2) (3 4) (5 6) (1 7)) #'+) > > -> ((5 6) (3 4) (1 9)) > > Multiply: > > (histogram '((1 2) (3 4) (5 6) (1 7)) #'*) > > -> ((5 6) (3 4) (1 14)) > > Add, supplying initial value for each summation: > > (histogram '((1 2) (3 4) (5 6) (1 7)) #'+ :initial-value 100) > > -> ((5 106) (3 104) (1 109)) Gauche Scheme: (define data '((a 2) (b 5) (a 4) (b 3) (c 9))) (rlet1 result '() (dolist (xs data) (ainc! result (car xs) (last xs)))) ((c . 9) (b . 8) (a . 6)) (rlet1 result '() (dolist (xs data) (ainc! result (car xs) (last xs) * 1))) ((c . 9) (b . 15) (a . 8)) (rlet1 result '() (dolist (xs data) (ainc! result (car xs) (last xs) + 7000))) ((c . 7009) (b . 7008) (a . 7006)) (rlet1 result '() (dolist (xs data) (ainc! result (car xs) (last xs) cons '()))) ((c 9) (b 3 5) (a 4 2)) Given: (define-syntax ainc! (syntax-rules () [(_ alist key val func default) (let ((pair (assoc key alist))) (if pair (set-cdr! pair (func val (cdr pair))) (set! alist (cons (cons key (func val default)) alist))))] [(_ alist key val func) (ainc! alist key val func 0)] [(_ alist key val) (ainc! alist key val +)] [(_ alist key) (ainc! alist key 1)]))