Clojureで、シンボル名とvectorを渡された場合に、そのアイテムを置き換える方法を知りたいです。
たとえば、次のインスタンスを置き換えたいとします。
[:not :symbolName]
と
(not symbolName)
そう:
[ [:p] [:not :q] [:not :r] [r] ]
次のようになります。
[ [:p] (not q) (not r) [r] ]
どんな助けでも大歓迎です、事前に多くの愛を^_^
(use '[clojure.walk :only (prewalk)])
(defn match? [x]
(and (vector? x)
(= (first x) :not)
(keyword? (second x))))
(defn transform [x]
(map (comp symbol name) x))
(defn replac [p t x]
(prewalk #(if (p %) (t %) %) x))
(replac match? transform [[:p] [:not :q] [:not :r] '[r]])
=> [[:p] (not q) (not r) [r]]
これはかなり一般的です。
(defn sym-replace [[x y] & syms]
(cond
(and x y (some #{x} syms)) (list (-> x name symbol) (-> y name symbol))
(and x y) [x y]
:else [x]))
例:
(def my-vec [[:p] [:not :q] [:not :r] ['r] [:foo :bar]])
(map #(sym-replace % :not) my-vec)
;; ([:p] (not q) (not r) [r] [:foo :bar])
(map #(sym-replace % :foo) my-vec)
;; ([:p] [:not :q] [:not :r] [r] (foo bar))
(map #(sym-replace % :not :foo) my-vec)
;; ([:p] (not q) (not r) [r] (foo bar))