XPost: comp.lang.scheme
John Gilson wrote:
Is there a standard Lisp function that will take a list and return an associative list representing the symbol frequency in the original list? For example, (frequency '(a (a (b) a))) => ((a . 3) (b . 1)). Any help would be greatly appreciated.
Thank you.
Coincidentally, someone else asked the same question earlier today.
(defun occurrences (list &key (test #'eql))
(if (consp list)
(let (alist)
(labels ((occurrences-aux (object)
(cond ((null object))
((consp object)
(occurrences-aux (first object))
(occurrences-aux (rest object)))
(t
(let ((count (assoc object alist :test test)))
(if (null count)
(setf alist (acons object 1 alist))
(incf (rest count))))))))
(occurrences-aux (first list))
(occurrences-aux (rest list)))
alist)))
(occurrences '(a (a (a b c) b c) b . c))
((C . 3) (B . 3) (A . 3))
Gauche Scheme:
(define (occurrences tree)
(rlet1 alist '()
(let go ((x tree))
(cond
((null? x))
((pair? x) (go (car x)) (go (cdr x)))
(#t (ainc! alist x))))))
(occurrences '(a (a (a b c) b c) b . c))
===>
((c . 3) (b . 3) (a . 3))
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)]))
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)