Привет, я новичок в clojure,
Я пытаюсь создать функцию, которая разбивает коллекцию на куски увеличивающегося размера, что-то вроде строк
(apply #(#(take %) (range 1 n)) col)
Где n - количество фрагментов
Пример ожидаемого результата: с n = 4 и col = (диапазон 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) вместо 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))
Строит ленивую последовательность, беря увеличивающиеся фрагменты из предоставленных xs, «повторяя» остальные
Нетерпеливое решение будет выглядеть так
(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))
Вы можете объяснить, что делает каждый шаг?