一連のアイテムが与えられた場合、頻度の高い順に n 個の最も頻繁なアイテムを見つけたいと考えています。したがって、たとえば、この単体テストに合格したいと思います。
(fact "can find 2 most common items in a sequence"
(most-frequent-n 2 ["a" "bb" "a" "x" "bb" "ccc" "dddd" "dddd" "bb" "dddd" "bb"])
=>
'("bb" "dddd"))
私は Clojure にかなり慣れていないので、まだ標準ライブラリを理解しようとしています。これが私が思いついたものです:
(defn- sort-by-val [s] (sort-by val s))
(defn- first-elements [pairs] (map #(get % 0) pairs))
(defn most-frequent-n [n items]
"return the most common n items, e.g.
(most-frequent-n 2 [:a :b :a :d :x :b :c :d :d :b :d :b]) =>
=> (:d :b)"
(take n (->
items ; [:a :b :a :d :x :b :c :d :d :b :d :b]
frequencies ; {:a 2, :b 4, :d 4, :x 1, :c 1}
seq ; ([:a 2] [:b 4] [:d 4] [:x 1] [:c 1])
sort-by-val ; ([:x 1] [:c 1] [:a 2] [:b 4] [:d 4])
reverse ; ([:d 4] [:b 4] [:a 2] [:c 1] [:x 1])
first-elements))) ; (:d :b :a :c :x)
ただし、これはかなり一般的な操作を行うための複雑な関数のチェーンのように見えます。これを行うためのより洗練された、またはより慣用的な (またはより効率的な) 方法はありますか?