如何创建一个懒惰-seq的矢量(How can I create a lazy-seq vector

2019-09-22 00:15发布

运行此按预期工作:

(defn long-seq [n]
  (lazy-seq (cons 
             (list n {:somekey (* n 2)})
             (long-seq (+ n 1)))))
(take 3 (long-seq 3))
; => ((3 {:somekey 6}) (4 {:somekey 8}) (5 {:somekey 10}))

不过,我愿做同样的事情用一个向量:

(defn long-seq-vec [n]
  (lazy-seq (into 
             (vector (list n {:somekey (* n 2)}))
             (long-seq-vec (+ n 1)))))
(take 3 (long-seq-vec 3))

这给了我一个堆栈溢出。 为什么?

Answer 1:

其主要原因是, 载体是不懒惰 -这样的into呼叫贪婪地消耗由产生的递归序列long-seq-vec并导致堆栈溢出。 由于这一推论,这是不可能创造无限向量(一般来说,你只能当它是懒惰或环创建了无限数据结构)。

它的工作原理在第一个例子,因为cons是相当愉快的行为时,懒洋洋地在consing一个懒惰的序列的前面,所以这个顺序可以是无限的。

假设你真正想要的矢量的无限序列我建议是这样的:

(defn long-seq-vec [n]
  (lazy-seq (cons 
              (vector n {:somekey (* n 2)})
              (long-seq-vec (+ n 1)))))

(take 3 (long-seq-vec 3))

=> ([3 {:somekey 6}] [4 {:somekey 8}] [5 {:somekey 10}])

或作为替代,你可以使用for ,这本身就是懒惰:

(defn long-seq-vec [n]
  (for [x (iterate inc n)]
    (vector x {:somekey (* x 2)})))

我喜欢这个,因为它避免了lazy-seq / cons样板,避免递归是在表达你的功能是什么稍微更清晰......这是一个有点多“的声明:”如果你喜欢。 您也可以使用map以类似的方式。



文章来源: How can I create a lazy-seq vector