Loops Clojure:当当前变量的值与输入值匹配时,如何使for循环停止?
前言 首先,我不熟悉Clojure和编程,所以我想我应该尝试创建一个函数,用我的本能来解决一个不平凡的方程。结果是想要找到一个平方根 问题 阻止square-n-map-maker函数迭代超过某个点的最有效方法是什么?我想修复square-n-map-maker,这样我就可以对square-maker函数进行注释,该函数提供了我当前想要查看的结果和格式,但无法回忆平方根答案(据我所知) 即,当它大于或等于我的输入值时,我希望它停止 我最初的想法是,我希望它是一张地图,而不是一个关键字列表。但是我很难让我的函数给我一张地图。我想要一个映射,其中一个成员是n,另一个是n^2,这样我就可以从中提取实际的平方根,并将其作为答案返回给用户 关于实现这一目标的最佳方法有什么想法吗?(以下是我要修复的函数)Loops Clojure:当当前变量的值与输入值匹配时,如何使for循环停止?,loops,for-loop,clojure,square-root,Loops,For Loop,Clojure,Square Root,前言 首先,我不熟悉Clojure和编程,所以我想我应该尝试创建一个函数,用我的本能来解决一个不平凡的方程。结果是想要找到一个平方根 问题 阻止square-n-map-maker函数迭代超过某个点的最有效方法是什么?我想修复square-n-map-maker,这样我就可以对square-maker函数进行注释,该函数提供了我当前想要查看的结果和格式,但无法回忆平方根答案(据我所知) 即,当它大于或等于我的输入值时,我希望它停止 我最初的想法是,我希望它是一张地图,而不是一个关键字列表。但是我
for
不是循环,也不是迭代。它惰性地创建列表理解,并且仅在需要时实现值(在本例中,当repl尝试打印评估结果时)。有两种常用的方法来完成您想要的操作:一种是将square-maker
包装在
(首先(过滤某个谓词(方形生成器编号)))
以获取序列中符合某个谓词的第一个元素。例如
(第一个(过滤器#)(和(奇数?%)(<50%))(范围))
=>51
显然,上述方法无法实现无限范围
另一种方法是不使用列表理解,而是以更迫切的方式执行:使用终止条件运行实际循环(请参见loop
和recur
)
例如:
(loop [x 0]
(if (and (odd? x) (> x 50))
x
(recur (inc x))))
阅读错误消息强> 你有点超前了!您的bug与停止“循环”无关 请注意错误消息。他们是你的朋友。在本例中,它告诉您将错误数量的参数传递给(搜索
IPersistentMap
)。那是什么
{}
创建映射文字{:key:value:key2:value2}
是一个映射。映射可以像函数一样使用:
> ({:key :value} :key)
:value
访问与密钥关联的映射中的条目的。现在,您在第一行中创建了一个映射:{rements culler input}
。您刚刚将函数余数剔除器映射到输入。如果你从地图中抓取一个项目,它就是一个地图条目
。每个MapEntry都可以用作函数,接受索引作为参数,就像向量一样:
> ([:a :b :c :d] 2)
:c
您的for
正在迭代{resident culler input}
中的所有映射项,但只有一个:[resident culler input]
。此映射项被分配给temp var
然后在下一行中,将此映射包装在括号中:(temp-var)
。这将形成一个表达式,并假设表达式中的第一项是函数/过程来计算表达式。因此它需要一个索引(这里的有效索引是0和1)。但是您不向temp var
传递任何参数。因此:clojure.lang.ArityException:参数数错误
另外,请注意,它不是的构造函数
构建地图
现在,谈谈你的问题。您的square-maker
正在返回一个格式良好的地图列表,但它是由嵌套列表组成的
试试这个:
(apply hash-map (flatten (square-maker 100)))
阅读并了解它是如何工作的
如果您不介意切换键和值的顺序,可以使用以下选项:
然后,您可以像这样获得所需的值:(first((square maker 100)100))
。这使用了我上面提到的map函数特性
循环
如果您真的想坚持直观循环的概念,我会使用,而不是for
。它是懒惰的,这意味着既没有方法也没有理由(如果你正确地使用它)来“阻止”它——它实际上不会做任何工作,除非你向它要求一个值,它只做它必须做的工作,给你你要求的值
(defn square-root [input]
(let [candidates (remainder-culler input)]
(loop [i 0]
(if (= input (#(* % %) (nth candidates i)))
(nth candidates i)
(recur (inc i))))))
嵌入的if
确定循环何时停止
但是请注意,loop
只返回它的最终值(如果这句话对您没有意义,请熟悉loop
的文档)。如果你想建立一个散列映射供以后分析,你必须做一些类似于(loop[i0,mymap{}]…
。但是如果可以马上完成,为什么还要在以后分析呢?:-)
现在,这是一个非常脆弱的平方根函数,要让它陷入无限循环并不难(feed it 101)。我把它作为一个练习留给你去修正它(不管怎么说,这都是一个学术练习,对吧?)
我希望这能再一次帮助你。我认为这是学习一门新语言的一个大问题。不过,我要说的是,作为记录,一旦你对自己的解决方案感到满意,你就应该解决这个问题,看看你是否能理解它们是如何工作的——这一个可能是“直观的”,但它并不适合Clojure的工具和功能。查看其他解决方案将帮助您更好地掌握Clojure的世界
更多阅读:
最后,这真的很有帮助,感谢您在这里提供的详细解释。
> ([:a :b :c :d] 2)
:c
(apply hash-map (flatten (square-maker 100)))
(defn square-maker [input]
(group-by #(* % %) (remainder-culler input)))
(square-maker 100) => {4 [2], 16 [4], 100 [10], 400 [20], 2500 [50]}
(defn square-root [input]
(let [candidates (remainder-culler input)]
(loop [i 0]
(if (= input (#(* % %) (nth candidates i)))
(nth candidates i)
(recur (inc i))))))