让我们制作频率图:
(reduce #(update-in %1 [%2] (fnil inc 0)) {} ["a" "b" "a" "c" "c" "a"])
我关心的是 lambda 中的表达式#(...)
- 这是规范的方法吗?我可以做得更好/更短吗?
编辑:我发现的另一种方式:
(reduce #(assoc %1 %2 (inc %1 %2 0)) {} ["a" "b" "a" "c" "c" "a"])
看起来非常相似,有什么优点/缺点?表现?
让我们制作频率图:
(reduce #(update-in %1 [%2] (fnil inc 0)) {} ["a" "b" "a" "c" "c" "a"])
我关心的是 lambda 中的表达式#(...)
- 这是规范的方法吗?我可以做得更好/更短吗?
编辑:我发现的另一种方式:
(reduce #(assoc %1 %2 (inc %1 %2 0)) {} ["a" "b" "a" "c" "c" "a"])
看起来非常相似,有什么优点/缺点?表现?
从 Clojure 1.2 开始,有一个frequencies
函数clojure.core
:
user=> (doc frequencies)
-------------------------
clojure.core/frequencies
([coll])
Returns a map from distinct items in coll to the number of times
they appear.
例子:
user=> (frequencies ["a" "b" "a" "c" "c" "a"])
{"a" 3, "b" 1, "c" 2}
它恰好使用瞬态和三元get
;请参阅(source frequencies)
代码,该代码在具有高度性能意识的同时非常惯用。
没有必要使用update-in
. 我的方式是:
(defn frequencies [coll]
(reduce (fn [m e]
(assoc m e (inc (m e 0))))
{} coll))
更新:我假设你也知道frequencies
核心,这只是一个练习。
前段时间我做了一个客座讲座,我在其中解释了如何逐步获得这个解决方案。因为您已经接近解决方案,所以对您来说并不新鲜core
,但也许它对阅读此问题的其他人有价值。幻灯片是荷兰语的。如果您将 .html 更改为 .org ,则更容易获得源代码:
http://michielborkent.nl/gastcollege-han-20-06-2013/gastcollege.html http://michielborkent.nl/gastcollege-han-20-06-2013/gastcollege.org
仅使用“关联”和递归的另一种方法:
(defn my-frequencies-helper [freqs a-seq]
(if (empty? a-seq)
freqs
(let [fst (first a-seq)
new_set (if (contains? freqs fst)
(assoc freqs fst (inc (get freqs fst)))
(assoc freqs fst 1))]
(my-frequencies-helper new_set (rest a-seq)))))
(defn my-frequencies [a-seq]
(my-frequencies-helper {} a-seq))
(我的频率 [1 1 2 2 :D :D :D])
=> {1 2, 2 2, :D 3}
(我的频率 [:a "moi" :a "moi" "moi" :a 1])
=> {:a 3, "moi" 3, 1 1}