我找到了以下代码(在this blog post中解决了Coin Changer Kata):
(defn change-for [amount]
(let [denominations [25 10 5 1]
amounts (reductions #(rem %1 %2) amount denominations)
coins (map #(int (/ %1 %2)) amounts denominations)]
(mapcat #(take %1 (repeat %2)) coins denominations)))
我觉得困难的部分是:(reductions #(rem %1 %2) amount denominations)
。
正如我发现的那样,reductions只是根据某个给定的函数逐步计算得到的集合。示例:(reductions + [1 2 3])
提供[1 3 6]
。
1 ; first element
1 + 2 ; second element
1 + 2 + 3 ; third element
计算余数的下一个函数rem仍然非常容易理解。
要了解其余的代码,我尝试了以下内容:
; first try, to see if this call works
; outside the original code (the change-for function)
(reductions #(rem %1 %2) 17 [10 5 1]) ; --> [17 7 2 0]
; tried to use the reductions which takes only one argument
; notice that 17 is now inside the array
(reductions #(rem %1 %2) [17 10 5 1]) ; --> [17 7 2 0]
; further simplified the expression
(reductions rem [17 10 5 1]) ; --> [17 7 2 0]
最后一步是删除this blog post中描述的匿名函数。
在这里,事情变得令人困惑(至少对我来说):rem
有两个参数,我不知道在使用数组[17 10 5 1]
时如何应用它们。我尝试了以下电话:
(rem [17 10 5 1]) ; --> gives error
(rem [17 10 5 1] [17 10 5 1]) ; --> also gives error
(rem 17 10) ; --> works, but how do you use it with collections?
有人可以解释一下,这个rem
函数如何与reductions
函数一起使用?
我不太明白的另一件事是:这些百分比参数是如何应用的(在#(rem %1 %2)
中)?我的意思是他们来自哪里?我尝试按以下方式调用rem
,但收到错误:(#(rem %1 %2) 17 [10 5 1])
。必须有reductions
函数在幕后进行这项工作,对吗?
起初我认为#(rem %1 %2)
是一套。它们以与集合类似的方式声明,并且很容易被滥用(有人刚开始使用Clojure):
(type #{1 2 3}) ; --> clojure.lang.PersistentHashSet
(type #(1 2 3)) ; --> user$eval12687$fn__12688
有人可以指向一个网站/书籍/任何解释Clojure技巧的内容,例如“匿名函数的特殊表格”吗?大多数资源只提供最简单的结构(类似于所有其他lisp衍生物的结构),而不涉及Clojure的复杂性。我发现a site看起来很不错(并且还解释了我上面提到的匿名函数)。 还有其他此类资源吗?
答案 0 :(得分:5)
此:
(reductions #(rem %1 %2) amount denominations)
相当于:
(reductions rem amount denominations)
正如您所注意到的那样
(reductions function start collection)
返回一系列中间结果,用collection
减少function
(将start
作为第一步减少的第一个参数)。 function
必须采用两个参数。
结果:
(reductions function start [1 2 3 4 5])
是
((function start 1) (function (function start 1) 2) ...)
#(rem %1 %2)
语法只是定义匿名函数的简写,它带有两个参数(%1
和%2
),对它们调用rem
并返回结果。< / p>
相当于:
(fn [a b] (rem a b))