在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."

如何在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."
  [[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))