elegant way to count items

elisp, emacs, lisp

Solution

I dunno that this is the most elegant, but it seems reasonable:

(defun add-for-cheeso (data)
  (let (result)
    (dolist (elt data result)
      (let ((sofar (assoc (car elt) result)))
        (if sofar
            (setcdr sofar (1+ (cdr sofar)))
          (push (cons (car elt) 1) result))))))

Problem

I have a list shaped like this: ``` '(("Alpha" . 1538) ("Beta" . 8036) ("Gamma" . 8990) ("Beta" . 10052) ("Alpha" . 12837) ("Beta" . 13634) ("Beta" . 14977) ("Beta" . 15719) ("Alpha" . 17075) ("Rho" . 18949) ("Gamma" . 21118) ("Gamma" . 26923) ("Alpha" . 31609)) ``` How can I count the total number of occurrences of the terms in the car of each element in the list? Basically I want: ``` (("Alpha" . 4) ("Beta" . 5) ("Gamma" . 3) ("Rho" . 1)) ``` No, this is not homework. I just don't have the "thinking in Lisp" thing quite yet. In C#, I would use LINQ to do this. I can do it in lisp, too, using while loops and such but the way I am thinking of doing it seems overly complicated. EDIT This is what I have: ``` (defun count-uniq (list) "Returns an alist, each item is a cons cell where the car is a unique element of LIST, and the cdr is the number of occurrences of that unique element in the list. " (flet ((helper (list new) (if (null list) new (let ((elt (assoc (car list) new))) (helper (cdr list) (if elt (progn (incf (cdr elt)) new) (cons (cons (car list) 1) new))))))) (nreverse (helper list nil)))) ```

Original source

Related problems