Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops Clojure:当当前变量的值与输入值匹配时,如何使for循环停止?_Loops_For Loop_Clojure_Square Root - Fatal编程技术网

Loops Clojure:当当前变量的值与输入值匹配时,如何使for循环停止?

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函数进行注释,该函数提供了我当前想要查看的结果和格式,但无法回忆平方根答案(据我所知) 即,当它大于或等于我的输入值时,我希望它停止 我最初的想法是,我希望它是一张地图,而不是一个关键字列表。但是我

前言 首先,我不熟悉Clojure和编程,所以我想我应该尝试创建一个函数,用我的本能来解决一个不平凡的方程。结果是想要找到一个平方根

问题 阻止square-n-map-maker函数迭代超过某个点的最有效方法是什么?我想修复square-n-map-maker,这样我就可以对square-maker函数进行注释,该函数提供了我当前想要查看的结果和格式,但无法回忆平方根答案(据我所知)

即,当它大于或等于我的输入值时,我希望它停止

我最初的想法是,我希望它是一张地图,而不是一个关键字列表。但是我很难让我的函数给我一张地图。我想要一个映射,其中一个成员是n,另一个是n^2,这样我就可以从中提取实际的平方根,并将其作为答案返回给用户

关于实现这一目标的最佳方法有什么想法吗?(以下是我要修复的函数)


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))))))