假設我有一個單一字符串的惰性序列,只包含'A''B'和'C'。從另一個laq seq創建一個Clojure laq seq,組合一些元素,刪除其他元素
我想從中創建第二個序列,其中包含與'A'連接的每個'A',並且直接跟隨'A'。輸入序列'C''B''A''B''A''A''B''C'將產生序列 'ABB''A''AB' 。
假設我有一個單一字符串的惰性序列,只包含'A''B'和'C'。從另一個laq seq創建一個Clojure laq seq,組合一些元素,刪除其他元素
我想從中創建第二個序列,其中包含與'A'連接的每個'A',並且直接跟隨'A'。輸入序列'C''B''A''B''A''A''B''C'將產生序列 'ABB''A''AB' 。
這裏有一個辦法做到這一點:
(defn austin [coll]
(lazy-seq
(when-let [[x & xs] (seq coll)]
(if (= x "A")
(let [[bs other] (split-with #(= % "B") xs)]
(cons (apply str x bs) (austin other)))
(austin xs)))))
(austin '("C" "B" "A" "B" "B" "A" "A" "B" "C")) ;=> ("ABB" "A" "AB")
首先,我們使用when-let
要麼解構輸入採集到的第一和休息(x
和xs
),或返回nil
- 終止遞歸 - 如果coll
爲空。
接下來,我們檢查x
是"A"
。如果是,我們使用split-with
將其餘項目拆分爲兩個seqs,即任何"B"
之一,緊跟其後的是其他所有。然後,我們使用str
將"A"
與我們找到的任何"B"
和cons
組合到一個遞歸延續過程中。
這可能不是最好的解決方案,但這裏是使用clojure.core/for
的工作代碼。
(def abc '("C" "B" "A" "B" "B" "A" "A" "B" "C"))
=> #'user/abc
(for [i (range (count abc))
:let [a (nth abc i)]
:when (= a "A")]
(apply str a (for [j (range (inc i) (count abc))
:let [b (nth abc j)]
:while (= b "B")]
b)))
=> ("ABB" "A" "AB")