我正在研究这个公案的解决方案,该公司声明:
Write a function which replicates each element of a sequence a variable number of times.
Run Code Online (Sandbox Code Playgroud)
要做到这一点,我想:
考虑到这一点,我写了以下方法:
(fn dupSeqX [aseq x]
(fn dupx [v x]
(if (= x 1) (list v) (concat v (dupx v (- x 1))))
)
(reverse (reduce #(concat %1 (dupx %2 x)) '() aseq)))
Run Code Online (Sandbox Code Playgroud)
运行此代码时,我收到以下错误:
java.security.PrivilegedActionException: java.lang.Exception: Unable to resolve symbol: dupx in this context (NO_SOURCE_FILE:0)
Run Code Online (Sandbox Code Playgroud)
我如何创建一个允许我完成这个公案的本地方法?
有没有"clojure-esque"这样做的方式,我不知道?
首先,我们不讨论方法:我们谈论功能.在clojure中你可以调用一个方法,但它与一个函数不同.如果你停止使用OO术语,你也会失去OO的思维方式.
你想做什么是可能的.您basiclly要创建一个名为新功能dupx
的dupseqx
功能.你现在正在做的是创建一个函数,然后抛弃它(你没有对返回值做任何事情,只返回函数中的最后一个表格).由于函数与任何其他值一样,您可以使用与任何其他值相同的机制:创建本地"变量".这个机制是什么?它是本地绑定,它的工作原理如下(fn中的名称只是为了你可以从它自己调用它;它不需要与绑定名称相同let
):
(let [dupx (fn dupx [v x]
(if (= x 1)
(list v)
(cons v (dupx v (dec x)))))]
(dupx 5 3))
Run Code Online (Sandbox Code Playgroud)
请注意,我更正了其他一些事情.
一个较短的形式(修复双重名称丑陋):
(letfn [(dupx [v x] (if (= x 1)
(list v)
(cons v (dupx v (dec x)))))]
(dupx 5 3))
Run Code Online (Sandbox Code Playgroud)
在"(让[...]"和匹配的")"之间的所有内容都可以,我们现在有了一个dupx
功能.
所以现在你的其余代码工作了:
(fn dupSeqX [aseq x]
(letfn [(dupx [v x] (if (= x 1) (list v) (cons v (dupx v (dec x)))))]
(reverse (reduce #(concat %1 (dupx %2 x)) '() aseq))))
Run Code Online (Sandbox Code Playgroud)
这段代码可以更加惯用:
coll
而不是aseq
我是怎么写这个的?
首先是基本的fn.coll
是期望序列的命名函数的标准.
(fn [coll times] )
Run Code Online (Sandbox Code Playgroud)
如果你读到这个"序列的每个元素"你的大脑必须去MAP.
(fn [coll times]
(map (fn ....) coll))
Run Code Online (Sandbox Code Playgroud)
"复制每个......"基本上是对你必须放入地图功能的描述.我们可以使用repeat
(你的dubx功能,但有一些额外的好东西,比如它很懒).
(fn [coll times]
(map (fn [val] (repeat times val)) coll))
Run Code Online (Sandbox Code Playgroud)
剩下一个问题(来自公案).它想要一个seq,而不是每个元素的序列中的序列.这意味着我们必须将结果连在一起.
(fn [coll times]
(apply concat (map (fn [val] (repeat times val)) coll)))
Run Code Online (Sandbox Code Playgroud)
你经常会看到这种(apply concat (map ....))
模式.在标准库中有一个更好的函数,称为mapcat
,我会将内部函数转换为短语法.
(fn [coll times]
(mapcat #(repeat times %) coll))
Run Code Online (Sandbox Code Playgroud)
希望有所帮助!