我想在数据结构内部搜索并替换值:
(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是地图中的键,因此不会被替换
答案 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})