* make mu:tabulate handle list values, add mu:top-n-most-frequent

- mu:tabulate will now add the values for lists (such as the mu recipient
    fields) as separate values
  - mu:top-n-most-frequent shows the <n> most frequent values
This commit is contained in:
djcb 2012-10-27 14:58:11 +03:00
parent f71ff24753
commit 4131506efb
1 changed files with 24 additions and 7 deletions

View File

@ -23,6 +23,7 @@
:use-module (ice-9 i18n) :use-module (ice-9 i18n)
:use-module (ice-9 r5rs) :use-module (ice-9 r5rs)
:export ( mu:tabulate :export ( mu:tabulate
mu:top-n-most-frequent
mu:count mu:count
mu:average mu:average
mu:stddev mu:stddev
@ -35,22 +36,38 @@
(define* (mu:tabulate func #:optional (expr #t)) (define* (mu:tabulate func #:optional (expr #t))
"Execute FUNC for each message matching EXPR, and return an alist "Execute FUNC for each message matching EXPR, and return an alist
with maps each result of FUNC to its frequency. FUNC is a function with maps each result of FUNC to its frequency. If the result of FUNC
takes a <mu-message> instance as its argument. For example, to is a list, add each of its values separately.
tabulate messages by weekday, one could use: FUNC is a function takes a <mu-message> instance as its argument. For
example, to tabulate messages by weekday, one could use:
(mu:tabulate (lambda(msg) (tm:wday (localtime (date msg))))), and (mu:tabulate (lambda(msg) (tm:wday (localtime (date msg))))), and
get back a list like get back a list like
((1 . 2) (2 . 5)(3 . 4)(4 . 4)(5 . 12)(6 . 7)(7. 2))." ((1 . 2) (2 . 5)(3 . 4)(4 . 4)(5 . 12)(6 . 7)(7. 2))."
(let ((table '())) (let* ((table '())
;; func to add a value to our table
(update-table
(lambda (val)
(let ((old-freq (or (assoc-ref table val) 0)))
(set! table (assoc-set! table val (1+ old-freq)))))))
(mu:for-each-message (mu:for-each-message
(lambda(msg) (lambda(msg)
(let* ((val (func msg)) (let ((val (func msg)))
(old-freq (or (assoc-ref table val) 0))) (if (list? val)
(set! table (assoc-set! table val (1+ old-freq))))) (for-each update-table val)
(update-table val))))
expr) expr)
table)) table))
(define* (top-n func less n #:optional (expr #t))
"Take the results of (mu:tabulate FUNC EXPR), sort using LESS (a
function taking two arguments A and B (cons cells, (VAL . FREQ)), and
returns #t if A < B, #f otherwise), and then take the first N."
(take (sort (mu:tabulate func expr) less) n))
(define* (mu:top-n-most-frequent func n #:optional (expr #t))
"Take the results of (mu:tabulate FUNC EXPR), and return the N items with the higest frequency."
(top-n func (lambda (a b) (> (cdr a) (cdr b))) n expr))
(define* (mu:count #:optional (expr #t)) (define* (mu:count #:optional (expr #t))
"Count the number of messages matching EXPR. If EXPR is not "Count the number of messages matching EXPR. If EXPR is not
provided, match /all/ messages." provided, match /all/ messages."