clojure 将集合拆分为大小不断增加的块
clojure split collection in chunks of increasing size
嗨,我是 clojure 新手,
我正在尝试创建一个函数,将集合拆分成大小不断增加的块,类似于
(apply #(#(take %) (range 1 n)) col)
其中 n 是块的数量
预期输出示例:
n = 4 且 col = (range 1 4)
(1) (2 3) (4)
n = 7 且 col =(范围 1 7)
(1) (2 3) (4 5 6) (7)
你可以这样使用:
(defn partition-inc
"Partition xs at increasing steps of n"
[n xs]
(lazy-seq
(when (seq xs)
(cons (take n xs)
(partition-inc (inc n) (drop n xs))))))
; (println (take 5 (partition-inc 1 (range))))
; → ((0) (1 2) (3 4 5) (6 7 8 9) (10 11 12 13 14))
或者如果你想有更大的影响力,你也可以提供
大小的序列(如果通过 (iterate inc 1)
for sizes
:
,则与上面的行为相同
(defn partition-sizes
"Partition xs into chunks given by sizes"
[sizes xs]
(lazy-seq
(when (and (seq sizes) (seq xs))
(let [n (first sizes)]
(cons (take n xs) (partition-sizes (rest sizes) (drop n xs)))))))
; (println (take 5 (partition-sizes (range 1 10 2) (range))))
; → ((0) (1 2 3) (4 5 6 7 8) (9 10 11 12 13 14 15) (16 17 18 19 20 21 22 23 24))
一个急切的解决方案看起来像
(defn partition-inc [coll]
(loop [rt [], c (seq coll), n 1]
(if (seq c)
(recur (conj rt (take n c)) (drop n c) (inc n))
rt)))
另一种方法是使用一些 clojure 序列函数:
(->> (reductions (fn [[_ x] n] (split-at n x))
[[] (range 1 8)]
(iterate inc 1))
(map first)
rest
(take-while seq))
;;=> ((1) (2 3) (4 5 6) (7))
另一种方法...
(defn growing-chunks [src]
(->> (range)
(reductions #(drop %2 %1) src)
(take-while seq)
(map-indexed take)
rest))
(growing-chunks [:a :b :c :d :e :f :g :h :i])
;; => ((:a) (:b :c) (:d :e :f) (:g :h :i))
嗨,我是 clojure 新手,
我正在尝试创建一个函数,将集合拆分成大小不断增加的块,类似于
(apply #(#(take %) (range 1 n)) col)
其中 n 是块的数量
预期输出示例: n = 4 且 col = (range 1 4)
(1) (2 3) (4)
n = 7 且 col =(范围 1 7)
(1) (2 3) (4 5 6) (7)
你可以这样使用:
(defn partition-inc
"Partition xs at increasing steps of n"
[n xs]
(lazy-seq
(when (seq xs)
(cons (take n xs)
(partition-inc (inc n) (drop n xs))))))
; (println (take 5 (partition-inc 1 (range))))
; → ((0) (1 2) (3 4 5) (6 7 8 9) (10 11 12 13 14))
或者如果你想有更大的影响力,你也可以提供
大小的序列(如果通过 (iterate inc 1)
for sizes
:
(defn partition-sizes
"Partition xs into chunks given by sizes"
[sizes xs]
(lazy-seq
(when (and (seq sizes) (seq xs))
(let [n (first sizes)]
(cons (take n xs) (partition-sizes (rest sizes) (drop n xs)))))))
; (println (take 5 (partition-sizes (range 1 10 2) (range))))
; → ((0) (1 2 3) (4 5 6 7 8) (9 10 11 12 13 14 15) (16 17 18 19 20 21 22 23 24))
一个急切的解决方案看起来像
(defn partition-inc [coll]
(loop [rt [], c (seq coll), n 1]
(if (seq c)
(recur (conj rt (take n c)) (drop n c) (inc n))
rt)))
另一种方法是使用一些 clojure 序列函数:
(->> (reductions (fn [[_ x] n] (split-at n x))
[[] (range 1 8)]
(iterate inc 1))
(map first)
rest
(take-while seq))
;;=> ((1) (2 3) (4 5 6) (7))
另一种方法...
(defn growing-chunks [src]
(->> (range)
(reductions #(drop %2 %1) src)
(take-while seq)
(map-indexed take)
rest))
(growing-chunks [:a :b :c :d :e :f :g :h :i])
;; => ((:a) (:b :c) (:d :e :f) (:g :h :i))