가장 자주 나타나는 항목을 빈도가 내림차순으로 찾고 싶습니다. 그래서 예를 들어 나는이 단위 테스트가 통과하고 싶습니다 :관용구 Clojure 가장 가까운 항목을 연속으로 찾는 방법
(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)
그러나이 작업은 상당히 일반적인 작업을 수행하는 복잡한 체인처럼 보입니다. 이것을하기위한 더 우아하고 관용적 인 (또는보다 효율적인) 방법이 있습니까?
감사합니다. Mikera, 귀하의 솔루션은 개선되었습니다. (1) 도우미 함수의 필요성을 피하기 위해 화살표 매크로를 올바르게 사용하는 방법을 본다. (2)'sort-by '는'seq'를 먼저 할 필요없이'frequency'의 결과에 직접적으로 작용할 수 있습니다. (3) 표준 라이브러리에는'first' 함수가 있으므로 내 라이브러리를 만들 필요가 없습니다. (4)'map '이전에'take '를하는 것이 더 효율적입니다. –
'(역순 (sort-by f coll))'은 진짜 이유가 없으므로 지독히 비쌉니다. 대신'(sort-by (comp-f) coll)'를 사용하십시오. 또한,'first'와'second' 또는'key'와'val'을 사용할 지에 대해서 일관성이 있습니다. 왜냐하면 그것들은 맵 엔트리와 동일하기 때문입니다. – amalloy