我一直在学习Clojure并对以下内容感到困惑:
user=> (for [a (range 1 4) b (range 1 4)] [a b])
([1 1] [1 2] [1 3] [2 1] [2 2] [2 3] [3 1] [3 2] [3 3]); _no surprise here_
让我们添加:while (not= a b)
,我希望看到一个空列表,因为如果条件为false,循环应该停止。在这种情况下,它是a
= b
= 1的第一个项目。我们来看看:
user=> (for [a (range 1 4) b (range 1 4) :while (not= a b) ] [a b])
([2 1] [3 1] [3 2]) ; _surprise!_
将:while
更改为:when
以过滤掉(= a b)
对
user=> (for [a (range 1 4) b (range 1 4) :when (not= a b) ] [a b])
([1 2] [1 3] [2 1] [2 3] [3 1] [3 2]); _expected_
有人能解释为什么(for [ ... :while ..] ...)
表现得像这样吗?
我在OS X上使用Clojure 1.3。
谢谢你,并为缺乏格式而道歉。这是我在StackOverflow上的处女帖。
答案 0 :(得分:9)
让我们看看每次迭代。
a = 1
b = 1 -> a == b, break because of while
a = 2
b = 1 -> a != b, print [2 1]
b = 2 -> a == b, break because of while
a = 3
b = 1 -> a != b, print [3 1]
b = 2 -> a != b, print [3 2]
b = 3 -> a == b, break because of while
答案 1 :(得分:3)
:while
中的for
条件仅终止最内层循环。我一直使用for
,但:while
很少,我从未意识到这一点;谢谢你提出的好问题!
可悲的是,我认为你能做的最好的事情是在take-while
周围包裹一个for
,因为你想要一个输出序列的“全局”停止计数器,而不是一个停止计数器。您正在迭代的输入序列。例如:
(->> (for [a (range 1 4)
b (range 1 4)]
[a b])
(take-while (fn [[a b]] (not= a b))))
()