elegant way to count items

后端 未结 9 1982
感情败类
感情败类 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:47

    Here's what I think is an elegant functional solution using Emacs' alist functions, yielding a reusable frequencies function similar to Eli's answer:

    (defun frequencies (vals)
      (reduce
       (lambda (freqs key)
         (cons (cons key (+ 1 (or (cdr (assoc key freqs)) 0)))
               (assq-delete-all-with-test key freqs 'equal)))
       vals
       :initial-value nil)))
    
    (frequencies (mapcar 'car
                         '(("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) ("Gamma" . 3) ("Rho" . 1) ("Beta" . 5))
    

提交回复
热议问题