Prev: Black-Jewish History FAQ - Is The Secret Relationship between blacks and jews a “hate literature”?
Next: which library to generate xml with namespaces?
From: Captain Obvious on 18 Jun 2010 09:31 R> IMHO a better way to approach this, particular for beginners, is to use R> abstract associative maps rather than association lists. A CL R> implementation of abstract associative maps can be found here: What's wrong with hash-tables which are in the standard? R> (defun count-items (list) R> (let ((c (make-instance 'counter))) R> (dolist (item list) (add c item)) R> c)) (defun count-items (list) (let ((ht (make-hash-table))) (dolist (item list) (incf (gethash item ht 0))) ht)) The only difference I see is that GETHASH accessor has default value and you can use INCF directly on it, no need for a goddamn additional function for that.
From: Tim Bradshaw on 18 Jun 2010 09:32 On 2010-06-18 14:11:55 +0100, Pascal J. Bourguignon said: > I think it's explained by the + after compound-form: it allows for > several forms to be executed in sequence in the finally clause. But if it allowed an unconditional there that would still be OK, you'd just need to say "finally do ... ..." since DO takes a compoint-form+ as well. This annoys me fairly frequently, I can't see a good reason for it.
From: refun on 18 Jun 2010 09:55 In article <87vfr3Ft2dU1(a)mid.individual.net>, eric(a)boese-wolf.eu says... > > Hello there! > > I'm starting to learn lisp and doing the exercises of Ansi Common Lisp > authored by Paul Graham. > > So my solution to counting occurences in a list and outputting a > list of dotted pairs (symbol . count) sorted by count is > > (defun occurences-helper (lst result) > (if (null lst) > result > (progn > (let ((symb (car lst))) > (let ((test (assoc symb result))) > (if test > (setf (cdr test) (+ (cdr test) 1)) > (setf result (cons (cons symb 1) result))))) > (occurences-helper (cdr lst) result)))) > > (defun occurences (lst) > (sort > (occurences-helper lst ()) > #'(lambda (x y) > (> > (cdr x) > (cdr y)))) > ) > > > And I thought: "Hmm that doesn't look elegant" but I'm not used to > recursion and functional programming and that stuff so I didn't > came up with a better version. > > Maybe some experienced lisp hacker may provide a different one? > > Yours sincerely, > > Eric Here's another hashtable-based solution: First, a function to convert a hashtable to an alist: (defun hashtable->alist (ht &aux alist) (maphash #'(lambda (key value) (push (cons key value) alist)) ht) (nreverse alist)) or with LOOP: (defun hashtable->alist (ht) (loop for key being the hash-keys in ht using (hash-value value) collect (cons key value))) The actual COUNT-OCCURANCES function: (defun count-occurances (list &aux (ht (make-hash-table))) (dolist (element list (sort (hashtable->alist ht) #'> :key #'cdr)) (incf (gethash element ht 0))))
From: Pascal Costanza on 18 Jun 2010 10:14 On 18/06/2010 09:19, Nicolas Neuss wrote: > "Frode V. Fjeld"<frode(a)netfonds.no> writes: > >> (defun occurences-helper (list) >> (loop with result = nil >> for element in list >> do (incf (getf result element)) >> finally (return result))) > > Small correction: (getf result element 0) Two functional versions (just out of curiosity): (defun count-elements (sequence &key (test #'eql)) (reduce (lambda (element result) (acons element (let ((cons (assoc element result :test test))) (if cons (1+ (cdr cons)) 1)) (remove element result :key #'car :test test))) sequence :initial-value '() :from-end t)) (defun count-elements/2 (sequence) (reduce (lambda (element result) (multiple-value-bind (indicator value tail) (get-properties result (list element)) (if indicator (list* element (1+ value) (nconc (ldiff result tail) (cddr tail))) (list* element 1 result)))) sequence :initial-value '() :from-end t)) I used :from-end to keep the elements in the order they appear in the original sequences. Pascal -- My website: http://p-cos.net Common Lisp Document Repository: http://cdr.eurolisp.org Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Frode V. Fjeld on 18 Jun 2010 10:32
Nicolas Neuss <lastname(a)kit.edu> writes: > "Frode V. Fjeld" <frode(a)netfonds.no> writes: > >> (defun occurences-helper (list) >> (loop with result = nil >> for element in list >> do (incf (getf result element)) >> finally (return result))) > > Small correction: (getf result element 0) Thanks, I guess I forgot to qualify all my code as "untested". -- Frode V. Fjeld |