элегантный способ подсчета элементов

У меня есть список такой формы:

  '(("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))

Как Могу ли я подсчитать общее количество вхождений терминов в машине каждого элемента в списке? В основном я хочу:

(("Alpha" . 4)
 ("Beta" . 5)
 ("Gamma" . 3)
 ("Rho" . 1))

Нет, это не домашнее задание. Просто у меня пока нет возможности "думать на Лиспе" .

В C # я бы использовал LINQ для этого. Я тоже могу делать это в lisp, используя циклы while и тому подобное, но то, как я думаю, это сделать, кажется слишком сложным.


EDIT

Это это то, что у меня есть:

(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))))
9
задан Cheeso 18 May 2011 в 19:54
поделиться