elegant way to count items

后端 未结 9 1998
感情败类
感情败类 2020-12-10 15:29

I have a list shaped like this:

  \'((\"Alpha\" .  1538)
    (\"Beta\"  .  8036)
    (\"Gamma\" .  8990)
    (\"Beta\"  .  10052)
    (\"Alpha\" .  12837)
           


        
9条回答
  •  孤城傲影
    2020-12-10 15:57

    Combining higher level Common Lisp functions:

    (defun count-unique (alist) 
      (mapcar
        (lambda (item)
          (cons (car item)
                (count (car item) alist :test #'equal :key #'car)))
        (remove-duplicates alist :test #'equal :key #'car)))
    

    It doesn't scale to large lists though. If you need O(n) performance use a hash table based solution instead, such as the less elegant:

    (defun count-unique (alist)
      (loop
         with hash = (make-hash-table :test #'equal)
         for (key . nil) in alist
         do (incf (gethash key hash 0))
         finally (return
                   (loop for key being each hash-key of hash
                      using (hash-value value)
                      collect (cons key value)))))
    

提交回复
热议问题