我如何实施一个懒惰的"减少地图"的功能?
题
我试图实现"减少地图"的功能。也就是说,它应该回序组成的,该结果应用 f
第2项 coll
, ,随后通过的结果应用 f
来,结果并的第三个项目在 coll
, 等等。
(def c [[0 0 0 0] [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1]])
(defn- sum-vector [v1 v2]
(map + v1 v2))
(defn reduce-map [f coll & acc]
(if (< (count coll) 2)
(if (empty? acc) coll acc)
(let [head (apply f (take 2 coll))
tail (drop 2 coll)]
(recur f (conj tail head) (conj acc head)))))
例如,这个叫功能是这样的:
(reduce-map sum-vector c)
应该返回:
[[1 0 0 0] [1 1 0 0] [1 1 1 0] [1 1 1 1]]
(实际上,它可能应该返回的第一个项目未经修改,以更好地模仿 map
, 但是我可以修复,之后。)
好的,现在,这是什么回报:
((1 1 1 1) (1 1 1 0) (1 1 0 0) (1 0 0 0))
怎么做我的"推动"在结束(纽约)seq?
如果我代替 reduce-map
对于 recur
, 这是什么回报:
(((1 1 1 1) ((1 1 1 0) ((1 1 0 0) ((1 0 0 0))))))
之间的区别是什么 recur
和真正的递归在我的代码吗?
而且, 是否有一个内置,或者更好,或者更多的惯用方式的实施 reduce-map
?
最后,我想输出序列偷懒。我只是包装的整个事情 lazy-seq
?
解决方案
这听起来有点像 reductions
.
作为"推动"在结束seq:在一般seqs没有一种"结束",cf。 (iterate inc 0)
.
作为"推动"在结束的一个清单:清单不是设计。使用一个向量。种子您的累加器与 []
, ,不 nil
.
作为对 lazy-seq
:使用"真正的"递归,而不是的 recur
.这里有一个例子:
(defn integer-seq
[start]
(lazy-seq
(cons start (integer-seq (inc start)))))
不隶属于 StackOverflow