合并地图,但有些值为零
merging maps, but some values are nil
所以我有两个地图,可以是任何东西,我想合并它们,但不包括 nil 值。
假设我有:
(def x {:a "A" :c 5 :d "D"})
(def y {:a 1 :b 2 :c nil})
我想结束
{:a 1 :b 2 :c 5 :d "D"}
如果我只是像 (merge x y) 那样合并,我会得到错误的 :c 值,但是 {:c nil} 在那里。我无法控制哪两张地图进来。任何帮助将不胜感激
您可以像这样轻松删除包含 nil
的地图条目:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[schema.core :as s]
))
(defn remove-nil-vals
[m]
(into {}
(for [[k v] m
:when (not (nil? v))]
[k v])))
(dotest
(let [x {:a "A" :c 5 :d "D"}
y {:a 1 :b 2 :c nil}
all-maps [x y]
merged-no-nils (into {}
(for [m all-maps]
(remove-nil-vals m)))]
(is= (remove-nil-vals x) {:a "A" :c 5 :d "D"})
(is= (remove-nil-vals y) {:a 1 :b 2})
(is= merged-no-nils {:a 1 :c 5 :d "D" :b 2})
))
以上是根据this template project.
如果您想以不让 nil
值覆盖非 nil
值的方式合并哈希映射,您可以使用 merge-with
:
dev=> (def x {:a "A" :c 5 :d "D"})
#'dev/x
dev=> (def y {:a 1 :b 2 :c nil})
#'dev/y
dev=> (merge-with (fn [a b] (if (some? b) b a)) x y)
{:a 1, :c 5, :d "D", :b 2}
dev=>
some?
returns true
如果它的参数是任何非 nil
值。
使用 into with the second argument being a filtering transducer 会生成一段相当简洁且可读性强的代码:
(def x {:a "A" :c 5 :d "D"})
(def y {:a 1 :b 2 :c nil})
(into x (filter (comp some? val)) y)
;; => {:a 1, :c 5, :d "D", :b 2}
如果您需要的话,只需要稍作调整即可从 first 映射中删除 nils:
(def x {:a "A" :c 5 :d "D" :e nil :f nil})
(def y {:a 1 :b 2 :c nil})
(into {} (comp cat (filter (comp some? val))) [x y])
;; => {:a 1, :c 5, :d "D", :b 2}
所以我有两个地图,可以是任何东西,我想合并它们,但不包括 nil 值。 假设我有:
(def x {:a "A" :c 5 :d "D"})
(def y {:a 1 :b 2 :c nil})
我想结束
{:a 1 :b 2 :c 5 :d "D"}
如果我只是像 (merge x y) 那样合并,我会得到错误的 :c 值,但是 {:c nil} 在那里。我无法控制哪两张地图进来。任何帮助将不胜感激
您可以像这样轻松删除包含 nil
的地图条目:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[schema.core :as s]
))
(defn remove-nil-vals
[m]
(into {}
(for [[k v] m
:when (not (nil? v))]
[k v])))
(dotest
(let [x {:a "A" :c 5 :d "D"}
y {:a 1 :b 2 :c nil}
all-maps [x y]
merged-no-nils (into {}
(for [m all-maps]
(remove-nil-vals m)))]
(is= (remove-nil-vals x) {:a "A" :c 5 :d "D"})
(is= (remove-nil-vals y) {:a 1 :b 2})
(is= merged-no-nils {:a 1 :c 5 :d "D" :b 2})
))
以上是根据this template project.
如果您想以不让 nil
值覆盖非 nil
值的方式合并哈希映射,您可以使用 merge-with
:
dev=> (def x {:a "A" :c 5 :d "D"})
#'dev/x
dev=> (def y {:a 1 :b 2 :c nil})
#'dev/y
dev=> (merge-with (fn [a b] (if (some? b) b a)) x y)
{:a 1, :c 5, :d "D", :b 2}
dev=>
some?
returns true
如果它的参数是任何非 nil
值。
使用 into with the second argument being a filtering transducer 会生成一段相当简洁且可读性强的代码:
(def x {:a "A" :c 5 :d "D"})
(def y {:a 1 :b 2 :c nil})
(into x (filter (comp some? val)) y)
;; => {:a 1, :c 5, :d "D", :b 2}
如果您需要的话,只需要稍作调整即可从 first 映射中删除 nils:
(def x {:a "A" :c 5 :d "D" :e nil :f nil})
(def y {:a 1 :b 2 :c nil})
(into {} (comp cat (filter (comp some? val))) [x y])
;; => {:a 1, :c 5, :d "D", :b 2}