我正在寻找一个类似于assoc-in的函数但删除键而不是添加它:
(dissoc-in {:a {:b 0}} [:a :b])
;;=> {:a {}}
Run Code Online (Sandbox Code Playgroud)
我起床到这里:
(def m {:a {:b {:c 1}}})
(assoc m :a (assoc (:a m) :b (dissoc (:b (:a m)) :c)))
;;=> {:a {:b {}}}
Run Code Online (Sandbox Code Playgroud)
但整个嵌套的东西都在弄乱我的脑袋
小智 89
我用update-in写这个:
(update-in {:a {:b 0 :c 1}} [:a] dissoc :b)
Run Code Online (Sandbox Code Playgroud)
=>
{:a {:c 1}}
Run Code Online (Sandbox Code Playgroud)
slo*_*oth 13
怎么样:
(defn dissoc-in
"Dissociates an entry from a nested associative structure returning a new
nested structure. keys is a sequence of keys. Any empty maps that result
will not be present in the new structure."
[m [k & ks :as keys]]
(if ks
(if-let [nextmap (get m k)]
(let [newmap (dissoc-in nextmap ks)]
(if (seq newmap)
(assoc m k newmap)
(dissoc m k)))
m)
(dissoc m k)))
Run Code Online (Sandbox Code Playgroud)
例:
(dissoc-in {:a {:b 0 :c 1}} [:a :b])
Run Code Online (Sandbox Code Playgroud)
结果:
{:a {:c 1}}
Run Code Online (Sandbox Code Playgroud)
dissoc-in曾经是其中的一部分clojure.contrib.core,现在也是其中的一部分core.incubator.
如果要保留空映射,可以稍微更改代码:
(defn dissoc-in
[m [k & ks :as keys]]
(if ks
(if-let [nextmap (get m k)]
(let [newmap (dissoc-in nextmap ks)]
(assoc m k newmap))
m)
(dissoc m k)))
Run Code Online (Sandbox Code Playgroud)
例:
(dissoc-in {:a {:b {:c 0}}} [:a :b])
Run Code Online (Sandbox Code Playgroud)
结果:
{:a {}}
Run Code Online (Sandbox Code Playgroud)
下面是一个基于 update-in 的通用解决方案:
(defn dissoc-in [m p]
(if (get-in m p)
(update-in m
(take (dec (count p)) p)
dissoc (last p))
m))
Run Code Online (Sandbox Code Playgroud)