我试图从clojuredocs.org中了解这个功能:
;; Create a word frequency map out of a large string s.
;; `s` is a long string containing a lot of words :)
(reduce #(assoc %1 %2 (inc (%1 %2 0)))
{}
(re-seq #"\w+" s))
; (This can also be done using the `frequencies` function.)
我不明白这一部分:(inc(%1%2 0))
答案 0 :(得分:3)
这是一个更易于理解的同一个例子,不使用匿名函数语法:
(reduce
(fn [acc elem]
(assoc acc elem (inc (acc elem 0))))
{}
(re-seq #"\w+" "a dog a cat a dog a banana"))
=> {"a" 4, "dog" 2, "cat" 1, "banana" 1}
此处acc
是我们正在构建的地图,elem
是当前的字词。让我们分解(inc (acc elem 0))
:
inc
将增加内部表达式返回的数字(acc elem 0)
将get
来自acc
地图的当前数字elem
,如果没有数字,则会返回{{1} }}。这是0
的缩写 - 地图也是函数,行为类似于(get acc elem 0)
函数。您还可以使用get
获得与(assoc acc elem (inc (acc elem 0)))
相同的效果。
使用带编号参数的匿名语法替换reduce函数时,同样的逻辑适用。
答案 1 :(得分:2)
传递给%1
的函数的第一个参数(匿名函数中的reduce
)是累加器,最初是作为第二个参数传递给{{}的空映射{}
。 1}}。映射是查找给定键的值的函数,如果未找到键,则返回可选的默认值,例如
reduce
和
({"word" 1} "word") = 1
所以
({"word" 1} "other" 0) = 0
在累加器映射中查找当前单词(缩减函数的第二个参数)的计数,如果尚未添加单词,则返回0。 (%1 %2 0)
增加当前计数,所以
inc
增加中间地图中当前单词的计数,或者如果这是第一次遇到该单词,则将其设置为1.
答案 2 :(得分:1)
您要问的代码基本上是that of the standard frequencies
function,其中transients已删除:
(defn frequencies [coll]
(reduce
(fn [counts x] (assoc counts x (inc (get counts x 0))))
{}
coll))
此
fn
表单而不是anonymous function literal(同样如此)
Taylor Wood above)和get
,它为我们提供了默认的线索
0
值。