鉴于此地图:
{:a nil
:b {:c nil
:d 2
:e {:f nil
:g 4}}}
我需要一个函数来删除所有的nil值,以便返回的map是
{:b {:e {:g 4}
:d 2}}
或者,当给出时:
{:a nil
:b {:c nil
:d nil
:e {:f nil
:g nil}}}
结果是:
nil
This question有一个答案,其中包含一个可能适用于嵌套地图的函数,但是当给定一个嵌套深度超过一级的地图时,该函数会失败。
答案 0 :(得分:7)
从这里修改答案https://stackoverflow.com/a/22186735/1393248
(defn remove-nils
"remove pairs of key-value that has nil value from a (possibly nested) map. also transform map to nil if all of its value are nil"
[nm]
(clojure.walk/postwalk
(fn [el]
(if (map? el)
(let [m (into {} (remove (comp nil? second) el))]
(when (seq m)
m))
el))
nm))
答案 1 :(得分:1)
(defn clean [m]
(if (map? m)
(let [clean-val (fn [[k v]]
(let [v' (clean v)]
(when-not (nil? v')
[k v'])))
m' (->> (map clean-val m)
(remove nil?)
(into {}))]
(when-not (empty? m') m'))
m))
答案 2 :(得分:0)
使用幽灵,您可以这样做:
(declarepath DEEP-MAP-VALS)
(providepath DEEP-MAP-VALS (if-path map? [(compact MAP-VALS) DEEP-MAP-VALS] STAY))
(setval [DEEP-MAP-VALS nil?] NONE
{:a nil
:b {:c nil
:d 2
:e {:f nil
:g 4}}})
请注意,如果什么也没剩下,它将返回:com.rpl.specter.impl/NONE
而不是nil
。
这是this答案的部分重用