Hi all, Given a list of sets of symbols, I want to rank the symbols based on how many sets they appear in. I prefer to be completely functional.
Below are 2 different implementations I came up with, with tests. I'm looking for criticism in any aspect, but most importantly I'm wondering whether there is a simpler implementation. Thanks. David ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #lang racket (require rackunit) (define (rank-set-elements/1 list-of-sets) (define list-of-lists (map set->list list-of-sets)) (define flat-list (flatten list-of-lists)) (define sorted-flat-list (sort flat-list symbol<?)) (define list-of-item-frequency-pairs (foldl (lambda (v accum) (match accum [(list-rest (cons sym cnt) rst) (if (eq? sym v) (cons (cons sym (add1 cnt)) rst) (cons (cons v 1) accum))] [else (list (cons v 1))])) '() sorted-flat-list)) (sort list-of-item-frequency-pairs > #:key cdr)) (define (rank-set-elements/2 list-of-sets) (define hash-of-item-frequencies (for*/fold ([frequencies (hash)]) ([a-set list-of-sets] [sym a-set]) (hash-update frequencies sym add1 0))) (define list-of-item-frequency-pairs (hash->list hash-of-item-frequencies)) (sort list-of-item-frequency-pairs > #:key cdr)) (define input (shuffle (map list->set '((a) (a b) (a b c) (a b c d) (a b c d e))))) (define expected '((a . 5) (b . 4) (c . 3) (d . 2) (e . 1))) (check-equal? (rank-set-elements/1 '()) '()) (check-equal? (rank-set-elements/1 input) expected) (check-equal? (rank-set-elements/2 '()) '()) (check-equal? (rank-set-elements/2 input) expected) ____________________ Racket Users list: http://lists.racket-lang.org/users