Mark Carter <me@privacy.net> wrote:
+---------------
| 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)
+---------------
Uh... What's wrong with just (MAPCAR #'FIRST *LIST*)?
[Oh, and your example output is wrong...]
+---------------
| 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) )
+---------------
If the lists were really, *really* big, with lots of duplicate keys,
I'd probably use a hash table to store keys & sums. Otherwise I'd just
use a dumb, simple, N^2 cost insertion sum. You know, something like this:
> (defun accum-by-key (list)
(loop with result = nil
for (first second) in list
do (let ((found (find first result :key #'first)))
(if found
(incf (second found) second)
(push (list first second) result)))
finally (return (reverse result))))
ACCUM-BY-KEY
> (accum-by-key *list*)
((1 9) (3 4) (5 6))
>
-Rob
p.s. I would have used a WHEN (FIND...) (INCF (SECOND IT) SECOND) ELSE...
except that IT can *only* be used in RETURN or accumulation clauses
(COLLECT, SUM, etc.). (*sigh*)
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607