Clojure разделяет коллекцию на куски увеличивающегося размера

Привет, я новичок в 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)
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
0
276
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Вы можете использовать что-то вроде этого:

(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))

Вы можете объяснить, что делает каждый шаг?

maazza 18.12.2020 18:01

Строит ленивую последовательность, беря увеличивающиеся фрагменты из предоставленных xs, «повторяя» остальные

cfrick 18.12.2020 18:04

Нетерпеливое решение будет выглядеть так

(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))

Другие вопросы по теме