Clojure中序列的延迟连接
这里有一个初学者的问题:在Clojure中有没有一种方法可以懒洋洋地连接任意数量的序列?我知道有宏,但我想不出它对任意数量序列的正确应用 我的用例是通过分页(偏移/限制)请求从API延迟加载数据。通过下面的Clojure中序列的延迟连接,clojure,lazy-evaluation,seq,Clojure,Lazy Evaluation,Seq,这里有一个初学者的问题:在Clojure中有没有一种方法可以懒洋洋地连接任意数量的序列?我知道有宏,但我想不出它对任意数量序列的正确应用 我的用例是通过分页(偏移/限制)请求从API延迟加载数据。通过下面的请求fn执行的每个请求检索100个结果: (map request-fn (iterate (partial + 100) 0)) 当没有更多结果时,request fn返回一个空序列。这就是我停止迭代的时候: (take-while seq (map request-fn (iterate
请求fn执行的每个请求检索100个结果:
(map request-fn (iterate (partial + 100) 0))
当没有更多结果时,request fn
返回一个空序列。这就是我停止迭代的时候:
(take-while seq (map request-fn (iterate (partial + 100) 0)))
例如,API可能返回多达500个结果,可以模拟为:
(defn request-fn [offset] (when (< offset 500) (list offset)))
有没有一种方法可以使用lazy cat
或其他方法来延迟连接结果序列?对于记录,apply
将只消耗足够的参数序列,因为它需要确定为提供的函数调用哪一个arity。由于concat
的最大arity为3,apply
将从基础序列中最多实现3项
如果这些API调用非常昂贵,并且您确实负担不起进行不必要的调用,那么您将需要一个函数,该函数接受一个seq的seq,并一次惰性地连接一个seq。我认为没有任何内置功能,但编写自己的功能相当简单:
(defn lazy-cat' [colls]
(lazy-seq
(if (seq colls)
(concat (first colls) (lazy-cat' (next colls))))))
仅根据需要计算每个参数。是的,但如何将其应用于一系列参数?您真的需要连接结果,还是只是想惰性地使用它们?将结果序列连接起来将使处理它们更容易。但这不是一个严格的要求。我还可以在结果页面上进行映射。感谢您对apply的澄清和对lazy cat的建议。回答得好;顺便说一句,当使用next
时,此函数急切地评估了colls
中的两个项目,即使只需要一次评估,例如(第一次(懒猫的aseq))
。相反,使用rest
给出了预期的行为。
(defn lazy-cat' [colls]
(lazy-seq
(if (seq colls)
(concat (first colls) (lazy-cat' (next colls))))))