/ / Разделяне с поредица от числа - clojure

Разделяне на поредица от числа - clojure

Какво би било по-идиоматичен начин да се раздели seq въз основа на seq на цели числа вместо само едно цяло число?

Ето моята реализация:

(defn partition-by-seq
"Return a lazy sequence of lists with a variable number of items each
determined by the n in ncoll.  Extra values in coll are dropped."
[ncoll coll]
(let [partition-coll (mapcat #(repeat % %) ncoll)]
(->> coll
(map vector partition-coll)
(partition-by first)
(map (partial map last)))))

Тогава (partition-by-seq [2 3 6] (range)) добиви ((0 1) (2 3 4) (5 6 7 8 9 10)).

Отговори:

3 за отговор № 1

Вариация на отговора на Анкур, с незначителна добавка на мързел when-let вместо изричен тест за empty?.

 (defn partition-by-seq [parts coll]
(lazy-seq
(when-let [s (seq parts)]
(cons
(take (first s) coll)
(partition-by-seq (rest s) (nthrest coll (first s)))))))

4 за отговор № 2

Вашата реализация изглежда добре, но може да има по-просто решение, което използва проста рекурсия lazy-seq(и се оказва по-ефикасно) от използването на карта и съществуващ дял като във вашия случай.

(defn partition-by-seq [ncoll coll]
(if (empty? ncoll)
"()
(let [n (first ncoll)]
(cons (take n coll)
(lazy-seq (partition-by-seq (rest ncoll) (drop n coll)))))))

2 за отговор № 3
(first (reduce (fn [[r l] n]
[(conj r (take n l)) (drop n l)])
[[] (range)]
[2 3 6]))

=> [(0 1) (2 3 4) (5 6 7 8 9 10)]