我有一个要求,在收到请求后,我必须从外部源获取值,过滤它们并将过滤后的值返回给调用者。我通过一次从外部源获取指定数量的记录来累积结果(直到达到所需的大小)。我设法提出了一个解决方案,但我不确定它是否是最优雅或惯用的方式。
请参阅下面的模拟代码,其中make-response函数必须将前50个奇数返回给调用者。 (请注意,此代码可能无法处理边缘情况,但我认为它足以用于演示目的)。
也许我应该使用ref代替原子?提前感谢任何建议。
(defn fetch [start]
(let [end (+ start 10)]
(range start end)))
(defn take-good-ones [all]
(filter odd? all))
(defn make-response []
(let [start (atom 0)
result (atom [])]
(while (< (count @result) 50)
(do
(let [all-values (fetch @start)
good-values (take-good-ones all-values)
handled-this-time (count all-values)]
(swap! start + handled-this-time)
(swap! result concat good-values))))
@result))
答案 0 :(得分:4)
不需要改变原子或低级循环的东西:
; the next 10 items since start
(defn fetch [start]
(range start (+ 10 start)))
; lazy sequence of good values, by getting batches of 10 from `fetch`
(defn all-good-values []
(filter odd?
(mapcat #(fetch (* 10 %)) (range))))
(defn make-response []
(take 20 (all-good-values)))
(make-response) => (1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39)
答案 1 :(得分:0)
除了Joost's answer之外,每个批次都被过滤然后连接,因此批处理没有任何效果。所以效果就是
(defn make-response []
(->> (range) (filter odd?) (take 50)))