At work we have some situations where we need to interleave lazy sequences in such a way that if one sequence is shorter than the other we want elements from the longer sequence to be concatenated after the interleaving runs out of the shorter sequence(s).
The following code could be used -- a slight variant of the existing interleave
function:
(defn interleave-all
"Like interleave, but stops when the longest seq is done, instead of
the shortest."
{:copyright "Rich Hickey, since this is a modified version of interleave"}
([] ())
([c1] (lazy-seq c1))
([c1 c2]
(lazy-seq
(let [s1 (seq c1) s2 (seq c2)]
(cond
(and s1 s2) ; there are elements left in both
(cons (first s1) (cons (first s2)
(interleave-all (rest s1) (rest s2))))
s1 ; s2 is done
s1
s2 ; s1 is done
s2))))
([c1 c2 & colls]
(lazy-seq
(let [ss (filter identity (map seq (conj colls c2 c1)))]
(concat (map first ss) (apply interleave-all (map rest ss)))))))