Clojure take-while и N больше предметов
каков идиоматический способ в Clojure реализовать take-while-and-n-more
ниже:
=> (take-while-and-n-more #(<= % 3) 1 (range 10))
(0 1 2 3 4)
моя попытка:
(defn take-while-and-n-more [pred n coll]
(let
[take-while-result (take-while pred coll)
n0 (count take-while-result)]
(concat
take-while-result
(into [] (take n (drop n0 coll))))))
3 ответов
Я хотел бы использовать сплит-с, что эквивалентно получению результатов как take-while, так и drop-while для тех же параметров:
(defn take-while-and-n-more [pred n coll]
(let [[head tail] (split-with pred coll)]
(concat head (take n tail))))
еще один способ:
(defn take-while-and-n-more [pred n coll]
(let [[a b] (split-with pred coll)]
(concat a (take n b))))
следующий код является модифицированной версией Clojures take-while
. Где Clojures take-while
возвращает nil
в качестве случая по умолчанию (когда предикат не совпадает), этот вызывает take
чтобы взять дополнительные элементы после сбоя предиката.
обратите внимание, что в отличие от версии с использованием split-with
, эта версия проходит последовательность только один раз.
(defn take-while-and-n-more
[pred n coll]
(lazy-seq
(when-let [s (seq coll)]
(if (pred (first s))
(cons (first s) (take-while-and-n-more pred n (rest s)))
(take n s)))))