Subject: Re: Basic List processing
From: rpw3@rpw3.org (Rob Warnock)
Date: Tue, 11 Nov 2008 06:48:54 -0600
Newsgroups: comp.lang.lisp
Message-ID: <rM2dnRxddaar4oTUnZ2dnUVZ_obinZ2d@speakeasy.net>
<JonathanSmith415@gmail.com> wrote:
+---------------
| Mark Carter <m...@privacy.net> wrote:
| > 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) )
| 
| (defun accum-pairlist (list)
|   (let ((return-list nil))
|     (dolist (li list)
|       (if (assoc (first li) return-list)
|           (setf (second (assoc (first li) return-list))
|                 (+
|                  (second (assoc (first li) return-list))
|                  (second li)))
|         (pushnew li return-list)))
|     return-list))
+---------------

Careful!! Your solution has the same bug that my first
(and, thankfully, unpublished!) version I did -- it doesn't
give the same answer twice. [And *why* it behaves that way
is even *more* serious!!]  E.g.:

    > (defvar *list* '((1 2) (3 4) (5 6) (1 7)))

    *LIST*
    > (accum-pairlist *list*)

    ((5 6) (3 4) (1 9))
    > (accum-pairlist *list*)

    ((5 6) (3 4) (1 16))
    > (accum-pairlist *list*)

    ((5 6) (3 4) (1 23))
    > 

Hint: What's wrong with the following?

    > *list*

    ((1 23) (3 4) (5 6) (1 7))
    > 


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607