Friday, April 17, 2009

Frequency table from sequences

Following function creates the frequency table from the given sequences.

(defn frequency-table  [& seqs]
(let [count-fn (fn [s item]
(update-in s [item] #(if % (inc %) 1)))]
(reduce #(reduce count-fn %1 %2) {} seqs)))

(frequency-table [1 2 3])
=> {3 1, 2 1, 1 1}

(frequency-table ["fred" "ethel" "lucy"] ["lucy" "rick"] ["lucy" "ethel" "john"])
=> {"john" 1, "rick" 1, "lucy" 3, "ethel" 2, "fred" 1}

(frequency-table '(1 2 3) #{4 2 1})
=> {4 1, 3 1, 2 2, 1 2}

(frequency-table {:a 1 :b 3} {:a 1 :b 4})
=> {[:b 4] 1, [:b 3] 1, [:a 1] 2}

2 comments:

  1. I solved the problem the same way, except I used a recur instead of a the second reduce. Nice example.


    (defn frequency-table [& seqs]
    (reduce (fn [m [i & seqs]]
    (if i
    (recur (update-in m [i] #(if % (inc %) 1)) seqs)
    m))
    {}
    seqs))

    ReplyDelete
  2. There's a function frequencies in 1.2 that almost does this. Try:

    (frequencies (concat ["fred" "ethel" "lucy"] ["lucy" "rick"] ["lucy" "ethel" "john"]))

    ReplyDelete