August 26, 2018
Just Juxt #12: Count Occurrences (4clojure #55)
Write a function which returns a map containing the number of occurrences of each distinct item in a sequence.
...but without using frequencies
!
(ns live.test
(:require [cljs.test :refer-macros [deftest is testing run-tests]]))
(defn freqs [s]
)
(deftest freqs-test
(is (= (freqs [1 1 2 3 2 1 1]) {1 4, 2 2, 3 1}))
(is (= (freqs [:b :a :b :a :b]) {:a 2, :b 3}))
(is (= (freqs '([1 2] [1 3] [1 3])) {[1 2] 1, [1 3] 2})))
(run-tests)
Here is the source for the frequencies
function:
user=> (source frequencies)
(defn frequencies
"Returns a map from distinct items in coll
to the number of times they appear."
{:added "1.2"
:static true}
[coll]
(persistent!
(reduce (fn [counts x]
(assoc! counts x (inc (get counts x 0))))
(transient {}) coll)))
Here's the juxt
ification:
(defn freqs [s]
(into {}
(map (juxt first count)
(partition-by identity (sort s)))))
(run-tests)
This is a pattern that we haven't yet seen - using juxt
to return a function and map
ing it.
Let's break this down:
(sort [1 1 2 3 2 1 1])
(partition-by identity '(1 1 1 1 2 2 3))
Now for the fun part, the 2 functions passed to juxt
. However, we're not calling it on the collection this time - instead we're map
ing it:
(first '(1 1 1 1))
(count '(1 1 1 1))
(first '(2 2))
(count '(2 2))
(first '(3))
(count '(3))
Which gives us:
(map (juxt first count)
'((1 1 1 1) (2 2) (3)))
Now all that's left to do is throw it into
a map
!
(into {} '([1 4] [2 2] [3 1]))
I hope you enjoyed today's juxt
, and possibly learned something. I know I sure did ;)