Я использую Clojure около месяца, так что я, вероятно, не обладаю достаточной квалификацией для выбора наиболее идиоматического способа;)
Но ваша реализация короткая и конкретная (игнорируя, что она также дублирует)встроенная функция раздел , как уже упоминалось).
Реализация уже достаточно независима от структуры данных - поскольку она использует последовательность операций, она работает со всеми стандартнымиструктуры данных:
(split 2 [1 2 3 4 5 6])
=> ((1 2) (2 3) (3 4) (4 5) (5 6))
(split 2 #{1 2 3 4 5 6})
=> ((1 2) (2 3) (3 4) (4 5) (5 6))
(split 2 {1 :a 2 :b 3 :c 4 :d})
=> (([1 :a] [2 :b]) ([2 :b] [3 :c]) ([3 :c] [4 :d]))
(split 2 "abcd")
=> ((\a \b) (\b \c) (\c \d))
Основное ограничение использования простой рекурсии состоит в том, что вы ограничены размером стека:
(split 2 (range 10000))
=> java.lang.StackOverflowError
Так что, если вы ожидаете, что входные размеры намного больше 1k, лучше использовать loop / recur, который не использует стек:
(defn split-loop [n coll]
(loop [elms coll res [] ]
(if (< (count elms) n)
res
(recur (next elms) (conj res (take n elms))))))