Clojure 地图的最高 3 个值
Clojure highest 3 values of a map
嗨,我正在尝试做一个函数,return是 3 个最常见的字符串
(take 3 (sort-by val > (frequencies s))))
(freq ["hi" "hi" "hi" "ola" "hello" "hello" "string" "str" "ola" "hello" "hello" "str"])
到目前为止我已经知道了,但是我注意到如果有超过 1 个字符串具有相同的频率,它就不会 return。有没有办法根据频率函数的最高值(最终是前 3 最高值)过滤频率函数的值?
提前致谢。
frequencies
给你一张地图,其中的键是原始值
调查并且该地图中的值是那些频率
值。对于您的结果,您对 all 原始值感兴趣,
出现次数最多的,包括那些原始值
相同的事件。
一种方法是“反转”频率结果,从中获取地图
与该事件一起出现的所有原始值。那么你就可以
获得最高的 N 个键并从这张地图和 select 他们(通过使用
用于反转地图的“排序地图”,我们可以通过键进行排序而无需
进一步的步骤)。
(defn invert-map
([source]
(invert-map source {}))
([source target]
(reduce (fn [m [k v]]
(update m v (fnil conj []) k))
target
source)))
(assert (=
{1 ["do" "re"]}
(invert-map {"do" 1 "re" 1})))
(defn freq
[n s]
(let [fs (invert-map (frequencies s) (sorted-map-by >))
top-keys (take n (keys fs))]
(select-keys fs top-keys)))
(assert (=
{4 ["hello"], 3 ["hi"], 2 ["ola" "str"]}
(freq 3 ["hi" "hi" "hi" "ola" "hello" "hello" "string" "str" "ola" "hello" "hello" "str"])))
我会提出略有不同的解决方案,其中涉及使用 group-by
值(即项目计数)反转频率图:
(->> data
frequencies
(group-by val))
;;{3 [["hi" 3]],
;; 2 [["ola" 2] ["str" 2]],
;; 4 [["hello" 4]],
;; 1 [["string" 1]]}
所以您唯一需要做的就是对其进行排序和处理:
(->> data
frequencies
(group-by val)
(sort-by key >)
(take 3)
(mapv (fn [[k vs]] {:count k :items (mapv first vs)})))
;;[{:count 4, :items ["hello"]}
;; {:count 3, :items ["hi"]}
;; {:count 2, :items ["ola" "str"]}]
嗨,我正在尝试做一个函数,return是 3 个最常见的字符串
(take 3 (sort-by val > (frequencies s))))
(freq ["hi" "hi" "hi" "ola" "hello" "hello" "string" "str" "ola" "hello" "hello" "str"])
到目前为止我已经知道了,但是我注意到如果有超过 1 个字符串具有相同的频率,它就不会 return。有没有办法根据频率函数的最高值(最终是前 3 最高值)过滤频率函数的值?
提前致谢。
frequencies
给你一张地图,其中的键是原始值
调查并且该地图中的值是那些频率
值。对于您的结果,您对 all 原始值感兴趣,
出现次数最多的,包括那些原始值
相同的事件。
一种方法是“反转”频率结果,从中获取地图 与该事件一起出现的所有原始值。那么你就可以 获得最高的 N 个键并从这张地图和 select 他们(通过使用 用于反转地图的“排序地图”,我们可以通过键进行排序而无需 进一步的步骤)。
(defn invert-map
([source]
(invert-map source {}))
([source target]
(reduce (fn [m [k v]]
(update m v (fnil conj []) k))
target
source)))
(assert (=
{1 ["do" "re"]}
(invert-map {"do" 1 "re" 1})))
(defn freq
[n s]
(let [fs (invert-map (frequencies s) (sorted-map-by >))
top-keys (take n (keys fs))]
(select-keys fs top-keys)))
(assert (=
{4 ["hello"], 3 ["hi"], 2 ["ola" "str"]}
(freq 3 ["hi" "hi" "hi" "ola" "hello" "hello" "string" "str" "ola" "hello" "hello" "str"])))
我会提出略有不同的解决方案,其中涉及使用 group-by
值(即项目计数)反转频率图:
(->> data
frequencies
(group-by val))
;;{3 [["hi" 3]],
;; 2 [["ola" 2] ["str" 2]],
;; 4 [["hello" 4]],
;; 1 [["string" 1]]}
所以您唯一需要做的就是对其进行排序和处理:
(->> data
frequencies
(group-by val)
(sort-by key >)
(take 3)
(mapv (fn [[k vs]] {:count k :items (mapv first vs)})))
;;[{:count 4, :items ["hello"]}
;; {:count 3, :items ["hi"]}
;; {:count 2, :items ["ola" "str"]}]