我希望使用以下代码
生成小于10的两个倍数(filter #(< % 10) (iterate (partial + 2) 2))
预期产出:
(2 4 6 8)
但是,出于某种原因,repl只是没有提供任何输出?
但是,下面的代码工作得很好......
(filter #(< % 10) '(2 4 6 8 10 12 14 16))
我理解一个是懒惰序列,一个是常规序列。这就是原因。但是,如果我希望从一个懒惰的序列中过滤掉所有小于10的数字,我怎么能克服这个问题......?
答案 0 :(得分:9)
(iterate (partial + 2) 2)
是无限序列。 filter
无法知道谓词为真的项目数是有限的,所以当你意识到序列时它会永远存在(参见马克答案)。 / p>
你想要的是:
(take-while #(< % 10) (iterate (partial + 2) 2))
答案 1 :(得分:5)
我想我应该注意Diego Basch's answer在其论证中并不完全正确:
filter
无法知道谓词为真的项目数是有限的,所以它将永远持续下去
为什么filter
应该知道一些事情?实际上filter
在这种情况下工作正常。可以对延迟序列应用filter
并获取另一个延迟序列,表示可能无限过滤数字序列:
user> (def my-seq (iterate (partial + 2) 2)) ; REPL won't be able to print this
;; => #'user/my-seq
user> (def filtered (filter #(< % 10) my-seq)) ; filter it without problems
;; => #'user/filtered
user>
这里的关键细节是,当实际序列不确定时,人们不应该试图(通过在OP的情况下打印)延迟序列(这样Clojure就知道了)。
当然,此示例仅用于演示目的,您应在此使用take-while
,而不是filter
。