【问题标题】:Function for replacing subsequences替换子序列的函数
【发布时间】:2014-10-30 16:22:37
【问题描述】:

有没有可以替换子序列的函数?例如:

user> (good-fnc [1 2 3 4 5] [1 2] [3 4 5])
;; => [3 4 5 3 4 5]

我知道字符串有clojure.string/replace

user> (clojure.string/replace "fat cat caught a rat" "a" "AA")
;; => "fAAt cAAt cAAught AA rAAt"

向量和列表有相似之处吗?

【问题讨论】:

    标签: list vector replace clojure sequence


    【解决方案1】:

    这对你有用吗?

    (defn good-fnc [s sub r]
      (loop [acc []
             s s]
        (cond
          (empty? s) (seq acc)
          (= (take (count sub) s) sub) (recur (apply conj acc r)
                                              (drop (count sub) s))
          :else (recur (conj acc (first s)) (rest s)))))
    

    【讨论】:

    • 是的,但我对标准函数感兴趣(我认为这是非常基本的操作,所以如果有字符串的东西,应该有向量和列表的东西......)
    • Clojure 字符串操作大多只是 jvm 互操作。一般序列不支持对字符串的许多操作。
    • @noisesmith,所以这意味着没有标准功能?
    • @Mark,什么语言对此有标准功能?
    • @ponzao,我不知道任何语言有标准功能,但是,每次我学习一些语言并做一些实际的事情时,我都需要这个功能,所以除非我完全独特,否则必须是对序列进行此类操作的库。
    【解决方案2】:

    这是一个与惰性 seq 输入配合得很好的版本。请注意,它可以采用无限惰性序列(range) 而不会像基于循环的版本那样无限循环。

    (defn sq-replace
      [match replacement sq]
      (let [matching (count match)]
        ((fn replace-in-sequence [[elt & elts :as sq]]
           (lazy-seq
            (cond (empty? sq)
                  ()
                  (= match (take matching sq))
                  (concat replacement (replace-in-sequence (drop matching sq)))
                  :default
                  (cons elt (replace-in-sequence elts)))))
         sq)))
    
    #'user/sq-replace
    user> (take 10 (sq-replace [3 4 5] ["hello, world"] (range)))
    (0 1 2 "hello, world" 6 7 8 9 10 11)
    

    我冒昧地将序列参数作为最后一个参数,因为这是 Clojure 中用于遍历序列的函数的约定。

    【讨论】:

    • 我用(apply str (sq-replace "a" "AA" "fat cat caught a rat"))" 测试了我的解决方案(原来是这个变相),得到"fat cat caught a rat"!怎么了?提示:(apply str (sq-replace (seq "a") "AA" "fat cat caught a rat")) 产生 "fAAt cAAt cAAught AA rAAt"。类型检查器会提供帮助的(罕见?)案例。
    【解决方案3】:

    我之前(现已删除)的答案不正确,因为这不像我最初想象的那么简单,这是我的第二次尝试:

    (defn seq-replace
      [coll sub rep]
      (letfn [(seq-replace' [coll]
                (when-let [s (seq coll)]
                  (let [start (take (count sub) s)
                        end (drop (count sub) s)]
                    (if (= start sub)
                      (lazy-cat rep (seq-replace' end))
                      (cons (first s) (lazy-seq (seq-replace' (rest s))))))))]
        (seq-replace' coll)))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-19
      • 2018-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多