ソリューションは 2 番目と 3 番目cond
の句で失敗します。シーケンスの 1 つが完全に使用されている場合は、残りの 1 つを最後に追加するだけです。おそらく、残りのコレクションを最初から他の 1 サイクルとマージする別の関数を呼び出す必要があります。例えば:
(defn- ext-interleave' [orig-xs xs orig-ys ys]
(let [xs (seq xs)
ys (seq ys)]
(cond
(and xs ys)
(concat
[(first xs) (first ys)]
(ext-interleave' orig-xs (rest xs) orig-ys (rest ys)))
xs
(interleave xs (cycle orig-ys))
ys
(interleave (cycle orig-xs) ys))))
(defn ext-interleave [xs ys]
(ext-interleave' xs xs ys ys))
(ext-interleave [1 2 3 4 5 6 7 8] '[a b c])
cond
この解決策は、最初のブランチでほとんど怠惰です (両方のシーケンスから最初の 2 つのアイテムを熱心に消費します) 。
怠惰なソリューションが必要ない場合は、既存の関数を使用してこれを機能させます。
cycle
+take
シーケンスを必要なだけ長くする
interleave
それらを組み合わせるコア
解決:
(defn ext-interleave [xs ys]
(let [l (max (count xs) (count ys))
xs (take l (cycle xs))
ys (take l (cycle ys))]
(interleave xs ys)))
(ext-interleave [1 2 3 4 5 6 7 8] '[a b c])
;; => (1 a 2 b 3 c 4 a 5 b 6 c 7 a 8 b)
任意の数の入力シーケンスに対して機能させることもできます。
(defn ext-interleave' [& cols]
(let [l (apply max (map count cols))
cols (map #(take l (cycle %)) cols)]
(apply interleave cols)))
(ext-interleave' [1 2 3 4 5 6 7 8] '[a b c] [:y :z])
;; => (1 a :y 2 b :z 3 c :y 4 a :z 5 b :y 6 c :z 7 a :y 8 b :z)
count
提供されたソリューションは、要素をカウントするために入力シーケンスを強制的に実現するため、怠惰ではありません。