从另一个懒惰的seq创建一个Clojure lazy seq,组合一些元素,删除其他元素

时间:2013-11-09 21:27:26

标签: clojure

假设我有一个单字符串的懒惰序列,只包含'A''B'和'C'。

我想从中创建第二个序列,其中包含与“B”一样多的'A'连接的每个'A',直接跟随'A'。

例如,输入序列'C''B''A''B''B''A'''''B''C'将产生序列 'ABB''A''AB'。

2 个答案:

答案 0 :(得分:3)

这是一种方法:

(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将输入集合解构为第一个和休息(xxs),或者返回nil - 终止递归 - 如果coll是空的。

接下来,我们会检查x是否为"A"。如果是,我们使用split-with将剩余的项目拆分为两个seq,其中一个是立即跟随的"B"之一,另一个是其他所有。然后,我们使用str"A"与我们找到的任何"B"以及cons结合到流程的递归延续中。

答案 1 :(得分:-1)

这可能不是最好的解决方案,但这里是使用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")