Remove nil values from a map?

2020-05-29 19:24发布

I have a Clojure map that may contain values that are nil and I'm trying to write a function to remove them, without much success (I'm new to this).

E.g.:

(def record {:a 1 :b 2 :c nil})
(merge (for [[k v] record :when (not (nil? v))] {k v}))

This results in a sequence of maps, which isn't what I expected from merge:

({:a 1} {:b 2})

I would like to have:

{:a 1, :b 2}

标签: clojure
9条回答
地球回转人心会变
2楼-- · 2020-05-29 20:14

Jürgen Hötzel solution refined to fix the nil/false issue

(into {} (filter #(not (nil? (val %))) {:a true :b false :c nil}))

A bit shorter version of @thnetos solution

(into {} (remove #(nil? (val %)) {:a true :b false :c nil}))
查看更多
趁早两清
3楼-- · 2020-05-29 20:16

Here's one that works on maps and vectors:

(defn compact
  [coll]
  (cond
    (vector? coll) (into [] (filter (complement nil?) coll))
    (map? coll) (into {} (filter (comp not nil? second) coll))))
查看更多
Lonely孤独者°
4楼-- · 2020-05-29 20:20

Here is one that works on nested maps:

(defn remove-nils
  [m]
  (let [f (fn [[k v]] (when v [k v]))]
    (postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
查看更多
登录 后发表回答