如何在Clojure脚本数据结构中进行搜索和替换?

时间:2014-09-18 14:42:11

标签: clojure clojurescript

我想在数据结构内部搜索并替换值:

(def str [1 2 3 
              {:a 1 
               :b 2 
               1  3}])

(subst  str  1  2) 

返回

[2 2 3 {:a 2, :b 2, 1 3}]

另一个例子:

(def str2  {[1 2 3] x, {a 1 b 2} y} )

(subst  str2  1  2) 

返回

{[1 2 3] x, {a 1 b 2} y}

由于1是地图中的键,因此不会被替换

1 个答案:

答案 0 :(得分:3)

一种选择是使用postwalk-replace

user> (def foo [1 2 3 
              {:a 1 
               :b 2 
               1  3}])
;; => #'user/foo
user> (postwalk-replace {1 2} foo)
;; => [2 2 3 {2 3, :b 2, :a 2}]

虽然,这种方法有一个缺点:它取代了结构中的所有元素,而不仅仅是值。这可能不是你想要的。


也许这会成功......

(defn my-replace [smap s]
  (letfn [(trns [s]
            (map (fn [x]
                   (if (coll? x)
                       (my-replace smap x)
                       (or (smap x) x)))
                 s))]
    (if (map? s)
      (zipmap (keys s) (trns (vals s)))
      (trns s))))

使用列表,矢量和地图:

user> (my-replace {1 2} foo)
;; => (2 2 3 {:a 2, :b 2, 1 3})

...似乎也可以处理任意嵌套结构:

user> (my-replace {1 2} [1 2 3 {:a [1 1 1] :b [3 2 1] 1 1}])
;; => (2 2 3 {:a (2 2 2), :b (3 2 2) 1 2})