从深度嵌套的映射中删除 nil 值
Remove nil values from deeply nested maps
给定这张地图:
{:a nil
:b {:c nil
:d 2
:e {:f nil
:g 4}}}
我需要一个函数来删除所有 nil 值,这样返回的映射是
{:b {:e {:g 4}
:d 2}}
或者,当给定时:
{:a nil
:b {:c nil
:d nil
:e {:f nil
:g nil}}}
结果是:
nil
This question 有一个答案,其中包含一个据称适用于嵌套地图的函数,但当给定嵌套超过一层深度的地图时,该函数会失败。
从这里修改答案
(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)
(not-empty (into {} (remove (comp nil? second)) el))
el))
nm))
(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))
使用幽灵你可以这样做:
(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}}})
请注意,如果没有剩余,它将 return :com.rpl.specter.impl/NONE
而不是 nil
。
这是 答案的部分重用
给定这张地图:
{:a nil
:b {:c nil
:d 2
:e {:f nil
:g 4}}}
我需要一个函数来删除所有 nil 值,这样返回的映射是
{:b {:e {:g 4}
:d 2}}
或者,当给定时:
{:a nil
:b {:c nil
:d nil
:e {:f nil
:g nil}}}
结果是:
nil
This question 有一个答案,其中包含一个据称适用于嵌套地图的函数,但当给定嵌套超过一层深度的地图时,该函数会失败。
从这里修改答案
(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)
(not-empty (into {} (remove (comp nil? second)) el))
el))
nm))
(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))
使用幽灵你可以这样做:
(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}}})
请注意,如果没有剩余,它将 return :com.rpl.specter.impl/NONE
而不是 nil
。
这是