在Clojure中将序列惰性地划分为大小不同的块
如何在Clojure中将序列惰性地划分为大小不同的块?有点像在Clojure中将序列惰性地划分为大小不同的块,clojure,partitioning,Clojure,Partitioning,如何在Clojure中将序列惰性地划分为大小不同的块?有点像(分区nxs),但是对于ns序列。例如: (chunker [3 4 5] (range 12)) => ((0 1 2) (3 4 5 6) (7 8 9 10 11)) 我需要这个来分块一些输入,不想使用Instaparse。下面是一个支持循环块大小的惰性解决方案: (defn chunker "Like (partition N input) but for a sequence of Ns."
(分区nxs)
,但是对于ns
序列。例如:
(chunker [3 4 5] (range 12))
=> ((0 1 2) (3 4 5 6) (7 8 9 10 11))
我需要这个来分块一些输入,不想使用Instaparse。下面是一个支持循环块大小的惰性解决方案:
(defn chunker
"Like (partition N input) but for a sequence of Ns."
[[chunk & chunks] coll]
(lazy-seq
(when-let [s (seq coll)]
(cons (take chunk s)
(when chunks (chunker chunks (drop chunk s)))))))
用法
这是关于我将如何写它,但你有点过于急切。
lazy seq
应该在顶层,而不是在cons
调用中:如果没有人请求元素,则不应该使用任何输入。你对块列表也太渴望了,但这没什么大不了的,因为大多数时候这些可能只是一个整数向量。@amalloy提到了clojure的实现。core/iterate
iterate
不消耗另一个输入序列,所以它不需要在第一项上偷懒。此外,在最近的版本中,iterate
根本没有在Clojure中实现,而是在Java中实现的,因此没有什么可比性。您应该改为与map
进行比较。谢谢,@amalloy!你是对的。固定的。即使未请求任何输入,以前的版本也很急切。其行为类似于分区所有
,而不是分区
。例如,(chunker[10](范围3))=>((0 1 2))
。但这可能是我们想要的。
(chunker [3 4 5] (range 20))
=> ((0 1 2) (3 4 5 6) (7 8 9 10 11)) ;; note not input not fully consumed.
(chunker (cycle [3 4 5]) (range 20))
=> ((0 1 2) (3 4 5 6) (7 8 9 10 11) (12 13 14) (15 16 17 18) (19))