Вы можете использовать lazy-seq
:
(defn left-fill-lazy [init coll]
(when (seq coll)
(lazy-seq
(let [v (first coll)
n (if (some? v) v init)]
(cons n (left-fill-lazy n (rest coll)))))))
(left-fill-lazy "a" '(nil nil "a" nil "c" nil "d" nil))
=> ("a" "a" "a" "a" "c" "c" "d" "d")
Вы можете использовать датчик, который отслеживает самое последнее значение, отличное от nil:
(defn left-fill
([] (left-fill nil))
([init]
(fn [rf]
(let [p (volatile! init)]
(fn
([] (rf))
([result] (rf result))
([result input]
(if (some? input)
(do (vreset! p input)
(rf result input))
(rf result @p))))))))
(sequence (left-fill "a") '(nil nil "a" nil "c" nil "d" nil))
=> ("a" "a" "a" "a" "c" "c" "d" "d")
Вы можете (ab) использовать молниидля того же эффекта:
(defn left-fill-zip [l]
(loop [loc (z/seq-zip l)]
(if (z/end? loc)
(z/root loc)
(recur
(z/next
(cond
(some? (z/node loc)) loc
(z/left loc) (z/replace loc (z/node (z/left loc)))
:else loc))))))
(left-fill-zip '("z" nil nil ("a" "b" ("c" nil) "d" nil)))
=> ("z" "z" "z" ("a" "b" ("c" "c") "d" "d"))