### Counting occurences (solution to the exercise)

unsorted — cgrand, 28 April 2009 @ 18 h 00 min
What does `(merge-with + {:a 12} {:b 4} {:a 3 :b 7})` return?
`{:b 11, :a 15}` when there are several values for a key, these values are merged (two at a time) using the specified function — here they are summed.
Can you count occurrences of each value in a collection using `merge-with`?
`(apply merge-with + (map (fn [x] {x 1}) coll))` or, using `for`: `(apply merge-with + (for [x coll] {x 1}))`.

### Counting occurences

unsorted — cgrand, 27 April 2009 @ 17 h 44 min

One asked me how to count occurrences of each value in a collection. I answered `(reduce #(assoc %1 %2 (inc (%1 %2 0))) {} coll)`. Since it can take some time to get accustomed to the functional way of thought, here is how one can work such an expression out:

How to count all occurrences of 42?
`(count (filter #{42} coll))`
How to express count using `reduce`?
`(defn my-count [coll] (reduce (fn [n _] (inc n)) 0 coll))`
How to count all occurrences of 42 using `reduce`?
`(reduce (fn [n _] (inc n)) 0 (filter #{42} coll))`
Can you get rid of the `filter`?
`(reduce (fn [n x] (if (= 42 x) (inc n) n)) 0 coll)`
I’d like the result to be `{42 occurences-count}`.
`(reduce (fn [m x] (if (= 42 x) (assoc m 42 (inc (m 42))) m)) {42 0} coll)`
42 is hardcoded in four places, it’s bad!
`(reduce (fn [m x] (if (= 42 x) (assoc m x (inc (m x))) m)) {42 0} coll)`
Can’t you replace `{42 0}` with `{}`?
No `(inc (m x))` would fail because `(m x)` would return `nil`.
How does one provide a default value when the key is not found ?
`(a-map a-key default-value)`
Can’t you replace `{42 0}` with `{}`?
`(reduce (fn [m x] (if (= 42 x) (assoc m x (inc (m x 0))) m)) {} coll)`
I changed my mind I’d like you to count occurrences of each value.
Easy! `(reduce (fn [m x] (assoc m x (inc (m x 0)))) {} coll)` or, terser, `(reduce #(assoc %1 %2 (inc (%1 %2 0))) {} coll)`

Exercise:

What does `(merge-with + {:a 12} {:b 4} {:a 3 :b 7})` return?
Can you count occurrences of each value in a collection using `merge-with`?