我发现以下代码(在解决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
接受2个参数,而使用数组[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看起来不错(并且还解释了我上面提到的匿名函数)。 还有其他此类资源吗?
最佳答案
这:
(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
并返回结果。等效于:
(fn [a b] (rem a b))
关于clojure - 请向我解释以下Clojure代码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13990214/